文章目录
- 一、定义英语单词信息的结构体
- 二、主函数功能逻辑
- 三、查单词函数
- 四、背单词函数
- 五、补充
一、定义英语单词信息的结构体
添加必要的头文件、宏定义和声明,之后定义英语单词信息结构体。
/* 头文件和宏定义 */#include #include #include #include /* 单词最大长度 和 单词定义最大长度 */#define MAX_WORD_LENGTH 20 #define MAX_DEFINITION_LENGTH 200/* 英语单词结构体定义 */struct EnglishWord{char word[MAX_WORD_LENGTH]; // 单词拼写char definition[MAX_DEFINITION_LENGTH]; // 单词定义};/* 函数声明 */void searchWord(const char *filename);void memorizeWord(const char *filename);
可以更改结构体的信息,以此来添加新功能。
添加另一个定义,之后可以收藏单词,查看收藏单词列表…
/* 结构体定义表示一个英文单词1、单词是否收藏2、单词拼写3、单词定义*/struct EnglishWord{int isFavorite;char word[MAX_WORD_LENGTH];char definition[MAX_DEFINITION_LENGTH];};
二、主函数功能逻辑
包含一个主循环,该循环持续显示菜单并等待用户输入。根据用户的选择,程序将执行相应的操作,如查单词、背单词或退出系统。在选择查询单词时,程序还包含一个嵌套循环,允许用户连续查询单词直到选择退出。程序会持续运行,直到用户选择退出系统。
/* 主函数*/int main(){// 定义int choice;while (1){printf("--------英语单词词典--------\n");printf("\t1. 查单词\n");printf("\t2、背单词\n");printf("\t0. 退出系统\n");printf("请选择操作:");scanf("%d", &choice);switch (choice){case 1:/* 连续查询 */while (1){char ch;searchWord("English.txt");printf("继续搜索单词(y/n): ");scanf(" %c", &ch); // 在%c前添加一个空格以跳过可能的空白字符while (getchar() != '\n');if (ch == 'n'){break;}}break;case 2:memorizeWord("English.txt");break;case 0:printf("成功退出系统。");exit(0);break;default:printf("无效选择,请重新输入!");}}return 0;}
- 主循环: 主函数采用了一个无限循环
while (1)
,使得用户可以在执行完一次操作后选择继续进行其他操作或退出系统。 - 菜单显示和选择: 主循环内部通过
printf
显示简单的菜单,包括查单词、背单词、退出系统的选项。使用scanf
获取用户的选择,并通过switch
语句根据用户的选择执行相应的操作。 - 操作执行:
switch
语句中根据用户的选择,执行相应的操作。如果用户选择查单词,则进入嵌套循环,调用searchWord
函数实现连续查询。如果用户选择背单词,则调用memorizeWord
函数执行背单词操作。如果用户选择退出系统,则输出退出信息并调用exit(0)
退出程序。- 查单词操作: 在选择查单词时,通过嵌套循环实现连续查询。用户可以在一次查询结束后选择是否继续查询,通过输入 ‘y’ 或 ‘n’ 决定。内部调用
searchWord
函数进行查询,保留用户的选择状态。 - 背单词操作: 在选择背单词时,调用
memorizeWord
函数执行背单词操作。用户在背单词的过程中可以通过按下任意键继续背下一个单词,包括 Enter 键。通过嵌套循环和非阻塞键盘输入的方式实现。 - 退出系统操作: 在选择退出系统时,输出退出信息并调用
exit(0)
退出程序,结束主循环。
- 查单词操作: 在选择查单词时,通过嵌套循环实现连续查询。用户可以在一次查询结束后选择是否继续查询,通过输入 ‘y’ 或 ‘n’ 决定。内部调用
三、查单词函数
这C语言函数用于在给定的文件中搜索指定的英文单词。
英语单词文件已进行资源绑定,可以在我的资源中进行查看。
void searchWord(const char *filename){// 变量定义FILE *file;int flag = 0;char searchWord[MAX_WORD_LENGTH];struct EnglishWord currentWord;// 打开文件,并检查是否打开成功if ((file = fopen(filename, "r")) == NULL){printf("无法打开文件 %s\n", filename);return;}// 获取用户输入待查找的英文单词printf("请输入待查找的英文单词(小写): ");scanf("%s", searchWord);// 遍历文件,查找匹配的英文单词while (fscanf(file, "%s %[^\n]", currentWord.word, currentWord.definition) != EOF){if (strncmp(currentWord.word, searchWord, strlen(searchWord)) == 0){printf("\t英文单词: %s\n\t解释: %s\n\n", currentWord.word, currentWord.definition);flag = 1;}}if (0 == flag) {printf("未找到英文单词:%s\n", searchWord);}// 关闭文件fclose(file);}
函数声明:
void searchWord(const char *filename);
参数:
filename
: 包含英文单词及其解释的文件名。
局部变量和结构体定义
FILE *file;int flag = 0;char searchWord[MAX_WORD_LENGTH];struct EnglishWord currentWord;
file
: 文件指针,用于打开和读取文件。flag
: 用于标记是否找到匹配的英文单词。searchWord
: 存储用户输入的待查找的英文单词。currentWord
: 结构体,包含英文单词和对应的解释。
文件打开检查:
if ((file = fopen(filename, "r")) == NULL){printf("无法打开文件 %s\n", filename);return;}
- 检查文件是否成功打开,如果未成功,则输出错误信息并返回。
用户输入待查找的英文单词:
printf("请输入待查找的英文单词(小写): ");scanf("%s", searchWord);
- 提示用户输入待查找的英文单词。
遍历文件并比较英文单词:
while (fscanf(file, "%s %[^\n]", currentWord.word, currentWord.definition) != EOF){// 检查是否找到匹配的英文单词if (strncmp(currentWord.word, searchWord, strlen(searchWord)) == 0){printf("\t英文单词: %s\n\t解释: %s\n\n", currentWord.word, currentWord.definition);flag = 1;}}
- 使用**
fscanf
**逐行读取文件内容,比较每一行的英文单词与用户输入的待查找单词。 - 如果找到匹配,输出英文单词和解释,设置**
flag
**为1。
- 使用**
输出结果:
if (0 == flag){printf("未找到英文单词:%s\n", searchWord);}
- 如果未找到匹配的英文单词,输出相应提示。
关闭文件:
fclose(file);
- 关闭打开的文件,以防止内存泄漏
四、背单词函数
通过逐个从文件中读取英文单词及其解释,使用户能够逐个记忆这些单词,并且能够读取上次结束的位置。
英语单词文件已进行资源绑定,可以在我的资源中进行查看。
void memorizeWord(const char *filename){// 变量定义char ch;FILE *file;FILE *recordFile;long lastPosition = 0;struct EnglishWord currentWord;// 打开文件,并检查是否打开成功if ((file = fopen(filename, "r")) == NULL){printf("无法打开文件 %s\n", filename);return;}// 获取文件最后载入位置if ((recordFile = fopen("position_record.txt", "r")) == NULL){printf("单词位置记录失败!");return;}else{fscanf(recordFile, "%ld", &lastPosition);fclose(recordFile);fseek(file, lastPosition, SEEK_SET);}// 逐一输入单词while (fscanf(file, "%s %[^\n]", currentWord.word, currentWord.definition) != EOF){FILE *recordFile;// 判断是否继续背单词printf("按任意键背下一单词(q to quit)");scanf(" %c", &ch);if (ch == 'q') { break; }while ((ch = getchar()) != '\n' && ch != EOF);printf("\t英文单词: %s\n\t解释: %s\n\n", currentWord.word, currentWord.definition);// 将本次读取的单词位置保存进新文件lastPosition = ftell(file);if ((recordFile = fopen("position_record.txt", "w")) == NULL){printf("单词位置记录失败!");}else{fprintf(recordFile, "%ld", lastPosition);fclose(recordFile);}}// 关闭文件fclose(file);}
打开文件:
- 函数接受一个文件名作为参数,并尝试以只读模式打开该文件。
- 如果文件打开失败,函数打印错误消息并返回。
if ((file = fopen(filename, "r")) == NULL){printf("无法打开文件 %s\n", filename);return;}
获取上次读取的位置:
- 函数尝试打开名为 “position_record.txt” 的记录文件,该文件保存上次读取的文件位置。
- 如果记录文件打开失败,函数打印错误消息并返回。
- 如果成功打开记录文件,函数读取上次读取的文件位置,并将文件指针移到该位置。
if ((recordFile = fopen("position_record.txt", "r")) == NULL){printf("单词位置记录失败!");return;}else{fscanf(recordFile, "%ld", &lastPosition);fclose(recordFile);fseek(file, lastPosition, SEEK_SET);}
逐个输入单词:
- 使用循环从文件中逐个读取英文单词及其解释,存储在结构体
struct EnglishWord
中。 - 在每个单词显示后,程序提示用户按任意键继续或按 ‘q’ 键退出。
- 用户按 ‘q’ 键退出时,循环终止。
while (fscanf(file, "%s %[^\n]", currentWord.word, currentWord.definition) != EOF){// ... (显示单词,等待用户输入)if (ch == 'q') { break; }// ... (保存当前读取位置)}
- 使用循环从文件中逐个读取英文单词及其解释,存储在结构体
记录当前读取位置:
- 在每次成功读取一个单词后,将当前文件指针位置保存到 “position_record.txt” 文件中,以便下一次程序运行时能够从上次中断的位置继续读取。
lastPosition = ftell(file);if ((recordFile = fopen("position_record.txt", "w")) == NULL){printf("单词位置记录失败!");}else{fprintf(recordFile, "%ld", lastPosition);fclose(recordFile);}
关闭文件:
- 最后关闭打开的文件。
fclose(file);
五、补充
完整程序
/* 相关头文件 */#include #include #include #include /* 单词最大长度 和 单词定义最大长度 */#define MAX_WORD_LENGTH 20#define MAX_DEFINITION_LENGTH 200// 结构体定义表示一个英文单词struct EnglishWord{char word[MAX_WORD_LENGTH];char definition[MAX_DEFINITION_LENGTH];};// 函数声明void searchWord(const char *filename);void memorizeWord(const char *filename);int main(){// 定义int choice;printf("--------英语单词词典--------\n");printf("\t1. 查单词\n");printf("\t2、背单词\n");printf("\t0. 退出系统\n");printf("请选择操作:");scanf("%d", &choice);switch(choice) {case 1: /* 连续查询 */while(1) {char ch;searchWord("English.txt");printf("继续搜索单词(y/n): ");scanf(" %c", &ch); // 在%c前添加一个空格以跳过可能的空白字符while(getchar() != '\n');if (ch == 'n') {break;}}break;case 2:memorizeWord("English.txt");break;default:printf("无效选择,请重新输入!");}return 0;}// 查找英文单词的函数void searchWord(const char *filename){/* 定义 */FILE *file;int flag = 0;char searchWord[MAX_WORD_LENGTH];struct EnglishWord currentWord;/* 打开文件,并检查是否打开成功 */if ((file = fopen(filename, "r")) == NULL){printf("无法打开文件 %s\n", filename);return;}printf("请输入待查找的英文单词(小写): ");scanf("%s", searchWord);/* 遍历文件,同时将格式化文件的内容逐一赋值到 word 和 definition 中 */while (fscanf(file, "%s %[^\n]", currentWord.word, currentWord.definition) != EOF){// 检查是否找到匹配的英文单词if (strncmp(currentWord.word, searchWord, strlen(searchWord)) == 0){printf("\t英文单词: %s\n\t解释: %s\n\n", currentWord.word, currentWord.definition);flag = 1;}}if (0 == flag) {printf("未找到英文单词:%s\n", searchWord);}// 一定要关闭文件,防止内存泄漏fclose(file);}void memorizeWord(const char *filename){char ch;FILE *file;FILE *recordFile;long lastPosition = 0; struct EnglishWord currentWord;// if ((file = fopen(filename, "r")) == NULL){printf("无法打开文件 %s\n", filename);return;}// 获取文件最后载入位置if ((recordFile = fopen("position_record.txt", "r")) == NULL){printf("单词位置记录失败!");return;}else {fscanf(recordFile, "%ld", &lastPosition);fclose(recordFile);fseek(file, lastPosition, SEEK_SET); }// 逐一输入单词while (fscanf(file, "%s %[^\n]", currentWord.word, currentWord.definition) != EOF){FILE *recordFile;/* 判断是否继续背单词 */printf("按任意键背下一单词(q to quit)");scanf(" %c", &ch); // 获取用户输入if (ch == 'q') { break; }while ((ch = getchar()) != '\n' && ch != EOF);printf("\t英文单词: %s\n\t解释: %s\n\n", currentWord.word, currentWord.definition);/* 将本次读取的单词位置保存进新文件 */lastPosition = ftell(file);if ((recordFile = fopen("position_record.txt", "w")) == NULL){printf("单词位置记录失败!");}else{fprintf(recordFile, "%ld", lastPosition);fclose(recordFile);}}fclose(file);}