需要的文件在我的主页,可以买免费下载
题意:
将一个字典文件存到链表中,在程序中输入一个英文单词,查询该输入单词的意思:
步骤:
1、将文件解析存到链表中
2、查找单词
3、释放内存
4、文件内容
代码实现
s思想:
创建一个链表,使用结构体,具有一个work, trans, next的指针,分别存储文件中的单词、单词的意思、指向下一个节点
然后输入一个单词,查找到这个单词,输出这个单词的意思就可以了
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<unistd.h>
#define LEN 2048
typedef struct Node {
char *word;
char *trans;
struct Node *next;
}Node;
/*
* 使用的是链表
*/
Node *loadDict(Node *head) {
char buff[LEN];
FILE *fp = fopen("./dict_e2c.txt", "r");
if (!fp) {
perror("open dict_e2c.txt file");
exit(1);
}
while(fgets(buff,LEN,fp)) {//读取文件, 一行一行的读取
Node *nn = (Node *)malloc(sizeof(Node));//创建一个新的节点
/*先读取第一行存的是单词*/
nn->word = (char *)malloc(sizeof(char)*(strlen(buff) + 1));
strcpy(nn->word, buff + 1);//buff[1]开始的位置复制到nn->word这个数组里面
nn->word[strlen(nn->word) - 1] = '\0';
/*读取第二行,存的是解释*/
fgets(buff,LEN,fp) ;
nn -> trans = (char *)malloc(sizeof(char)*(strlen(buff) + 1));
strcpy(nn->trans, buff + 6);
//buff[1]开始的位置复制到nn->word这个数组里面,我们的文件案例前面多了Trans: --> 所以从第六个开始
nn -> word[strlen(nn->word) - 1] = '\0';
//头插法
nn->next = head;
head = nn;
}
fclose(fp);
return head;
}
/*
*查找单词
*/
Node * findTrans(Node *head, char *iptwd) {
// char iptwd[100] 相当于char *iptwd,指针来的
Node *p = head;
while (p && strcmp(iptwd, p->word)) { //strcmp相等时返回0
p = p -> next;
}
return p;
}
void freeSys(Node *head) {
Node *p = head;
Node *k;
while(p) {
k = p;
p = p -> next;
free(k -> word);
free(k -> trans);
free(k -> next);
free(k);
}
return ;
}
int main(void){
Node *head = NULL;
head = loadDict(head);//要设置返回值
char iptwd[100];//读取字符,查找单词
while(1) {
printf("please input a word: ");
scanf("%s", iptwd);
if(!strcmp(iptwd, "__quit")) {//相同的话返回值为0, 输入字符串 __quit退出程序
break;
}
Node *tmp = findTrans(head, iptwd);//查找单词的操作
if(tmp)
printf("%s",tmp->trans);
else
printf("your word not found^_^!\n");
}
printf("see you~~~\n");
freeSys(head);//释放系统
return 0;
}
代码优化:
上面的写法太浪费空间,我们可以存储一个序号,就是单词的序号,这样子就可以就不用创建一个属于trans的空间了,当我们查找到这个单词的时候,输出相应序号对应的解释就好了
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<unistd.h>
#define LEN 2048
typedef struct Node {
char *word;
//char *trans;
int idx; //索引
struct Node *next;
}Node;
/*
* 使用的是链表
*/
Node *loadDict(Node *head) {
char buff[LEN];
FILE *fp = fopen("./dict_e2c.txt", "r");
if (!fp) {
perror("open dict_e2c.txt file");
exit(1);
}
while(fgets(buff,LEN,fp)) {//读取文件
Node *nn = (Node *)malloc(sizeof(Node));//创建一个新的节点
/*先读取第一行存的是单词*/
nn->word = (char *)malloc(sizeof(char)*(strlen(buff) + 1));
strcpy(nn->word, buff + 1);//buff[1]开始的位置复制到nn->word这个数组里面
nn->word[strlen(nn->word) - 1] = '\0';
nn -> idx = ftell(fp);//存下索引的位置
// fgets(buff,LEN,fp) ;//读取buff中内容
// nn -> trans = (char *)malloc(sizeof(char)*(strlen(buff) + 1));
// strcpy(nn->trans, buff + 6);//buff[1]开始的位置复制到nn->word这个数组里面
//nn -> word[strlen(nn->word) - 1] = '\0';
//头插法
nn->next = head;
head = nn;
}
fclose(fp);
return head;
}
/*
*查找单词
*/
Node * findTrans(Node *head, char *iptwd) {
// char iptwd[100] 相当于char *iptwd,指针来的
Node *p = head;
while (p && strcmp(iptwd, p->word)) { //strcmp相等时返回0
p = p -> next;
}
return p;
}
void freeSys(Node *head) {
Node *p = head;
Node *k;
while(p) {
k = p;
p = p -> next;
free(k -> word);
// free(k -> trans);
free(k -> next);
free(k);
}
return ;
}
int main(void){
Node *head = NULL;
head = loadDict(head);//要设置返回值
char iptwd[100];//读取字符,查找单词
char buff[LEN];
FILE *fp = fopen("./dict_e2c.txt", "r");
if (!fp) {
perror("open dict_e2c.txt file");
exit(1);
}
while(1) {
printf("please input a word: ");
scanf("%s", iptwd);
if(!strcmp(iptwd, "__quit")) {//相同的话返回值为0
break;
}
Node *tmp = findTrans(head, iptwd);//查找单词的操作
if(tmp){
// printf("%s",tmp->trans);
fseek(fp, tmp -> idx, SEEK_SET);//设置指针到idx的位置
fgets(buff, LEN,fp);//解释存入buff数组中
printf("%s", buff);
} else
printf("your word not found^_^!\n");
}
fclose(fp);
printf("see you~~~\n");
freeSys(head);//释放系统
return 0;
}
fgets(buff, LEN,fp);//解释存入buff数组中
printf("%s", buff);
} else
printf("your word not found^_^!\n");
}
fclose(fp);
printf("see you~~~\n");
freeSys(head);//释放系统
return 0;
}
> 写于2021-08-20