功能

实现输入英语单词输出对应的中文意思

算法

1、导入整理好的英汉小词典文件到哈希表中

2、建立以单词首字母为key的索引表

3、获取输入单词的key,查找索引表,找到中文释义输出

关键点

1、文件的读入操作:fopen()、fgets()

2、对字符串的处理及存储

3、哈希表的建立、查询

两个函数

#include <stdio.h>
FILE *fopen(const char *path, const char *mode);

//示例
FILE *f = fopen("./xxx.txt","r");//文件的相对路径或绝对路径
if(f==NULL)printf("文件打开失败!\n");

FILE :数据对象类型(控制块),记录一个流的状态

流:逻辑数据流,数据流入或流出缓冲区,是一块堆区的内存空间

文本流:文本行的有序字符序列,每一行有换行符

二进制流:字符的有序序列

函数fopen打开名为path(路径加文件名.扩展名)的文件,并把这个文件和一个流相关联。参数mode指向以下列出的字符开头的字符串

“r”:以只读权限打开path的文件

“rb”:以只读权限打开path的二进制文件

函数fopen返回指向控制流的对象的指针。如果打开文件失败,返回NULL

#include <stdio.h>
char *fgets(char *s,int n,FILE *stream);

//示例
char s1[10],s2[20];
FILE *f = fopen("./xxx.txt","r");
fgets(s1,10,f);//从文件f中读取一行字符串并存入s1数组中
if(fgets(s2,20,stdin)!=NULL){//从标准输入流(键盘)读取字符并存入s2数组中
    语句块;
}

函数fgets从stream指向的流中读取字符,读取字符的数目最多为n-1,然后将字符写入到s指向的数组中。读入换行符('\n')(保留)或者文件结束不再读取字符。最后一个字符写入数组后立即写入一个'\0'。

△linux文件一行末尾以\n结尾、windows以\r结尾、unix以\r\n结尾

如果执行成功,返回s;如果遇到文件结束并没有向数组中写入字符,则数组的内容不变且返回一个空指针;如果操作发生读错误,则数组内容不确定且返回一个空指针。

stream指针有以下几个:

stderr:指向标准错误流对象

stdin:指向标准输入流对象

stdout:指向标准输出流对象

<code>

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SIZE 100   //文本一行字符串读取长度限制
#define INDEX 26   //索引表容量
#define EN 30    //英文字符串长度限制
#define CN 70    //中文字符串长度限制
typedef struct vocabulary{
    char key;
    char en_word[EN];//存储英文
    char ch_word[CN];//存储中文
    struct vocabulary *next;
}Word,*WORD;
//创建Hash表
WORD *create()
{
    int i;
    WORD *hash = (WORD*)malloc(INDEX);
    for(i=0;i<INDEX;i++)
    {
        hash[i] = (WORD)malloc(sizeof(Word));
        hash[i]->key = 'a'+i;
        memset(hash[i]->en_word,0,sizeof(char)*EN);
        memset(hash[i]->ch_word,0,sizeof(char)*CN);
        hash[i]->next = NULL;
    }
    return hash;
}
//插入单词到Hash表
void insert(WORD* hash,char *word)
{
    //拆分中英文
    char en[EN]="",ch[CN]="";
    int en_len=0,ch_len=0;
    char *p=word;
    while(*p!=' ')
    {
        p++;
        en_len++;
    }
    strncpy(en,word,en_len);//得到英文
    while(*p==' ')p++;
    char *c=p;
    while(*p!='\0')
    {
        p++;
        ch_len++;
    }
    strncpy(ch,c,ch_len);//得到释义中文
    //获取key
    char key[2]="";
    strncpy(key,word,1);
    //创建单词结点
    WORD node = (WORD)malloc(sizeof(Word));
    node->key = key[0];
    strcpy(node->en_word,en);
    strcpy(node->ch_word,ch);
    //strcpy(node->en_word,word);//test
    //strcpy(node->ch_word,word);//test
    //头插法
    WORD head = hash[node->key-'a'];
    node->next = head->next;
    head->next = node;
}
//打印Hash表
void printHash(WORD* hash)
{
    int i;
    WORD h;
    for(i=0;i<INDEX;i++)
    {
        h = hash[i];
        while(h->next!=NULL)
        {
            h = h->next;
            printf("%s\n",h->en_word);
            //printf("%d\n",strlen(h->en_word));//test
            printf("%s\n",h->ch_word);
        }
    }
}
//查询英文的释义
void find(WORD* hash,char *vocabulary)
{
    char key[2]="";
    strncpy(key,vocabulary,1);
    WORD p=hash[key[0]-'a']->next;
    //printf("%c %d\n",key[0],key[0]-'a');//test
    while(p!=NULL)
    {
        if(!strcmp(p->en_word,vocabulary))
        {
            printf("%s",p->ch_word);
            return;
        }
        p=p->next;
    }
    printf("词典中没有这个单词\n");
}
int main(int argc, const char *argv[])
{
    FILE *f = fopen("./牛津英汉小词典.txt","r");
    if(f==NULL){
        printf("读取失败\n");
        return 0;
    }
    char word[SIZE] = "";
    WORD *hash = create();
    while(fgets(word,SIZE,f)!=NULL)
    {
        insert(hash,word);
        //printf("%s",word);//test
    }
    fclose(f);//读取完毕释放空间
    printHash(hash);//test
    char vocabulary[EN]="";
    printf("请输入你要查询的英文单词-->");
    if(fgets(vocabulary,EN,stdin)!=NULL){//会多读一个'\n'
        vocabulary[strlen(vocabulary)-1] = '\0';
        //printf("%d\n",strlen(vocabulary));//test
        find(hash,vocabulary);
    }
    return 0;
}

调试

调试过程中出现过段错误

定位

这里出现段错误就2种可能:①哈希表中指针的错误访问;②字符串指针的越界

先将字符串处理的函数全部注释掉,再将英文中文整串字符串word都存入数组en_word和ch_word中,调用打印哈希表全部内容测试,发现没有问题,能全部打印

定位到void insert(WORD* hash,char *word)函数中的拆分中英文部分语句块

检查

①字符串的定义、及容量设置是否小了;②字符串处理函数strncpy()的用法是否无误

发现字符串的定义出错了,指针变量指向的空间里存储的内容成了一个字符串常量

错误定义如下:

char *en = "",*ch = "";
char *key = "";

修改正确如下:

char en[EN] = "",ch[CN] = "";
char key[2] = "";

测试

结果

请输入你要查询的英文单词-->cod
词典中没有这个单词

请输入你要查询的英文单词-->code
n.法规,代码,密码

牛津英汉小词典.txt

Last modification:2021 年 03 月 29 日 11 : 35 : 37