【C语言】简易英语词典

文章目录

一、定义英语单词信息的结构体

添加必要的头文件、宏定义和声明,之后定义英语单词信息结构体。

c 复制代码
/* 头文件和宏定义 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

/* 单词最大长度 和 单词定义最大长度 */
#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);

可以更改结构体的信息,以此来添加新功能。

添加另一个定义,之后可以收藏单词,查看收藏单词列表...

c 复制代码
/* 
    结构体定义表示一个英文单词
    1、单词是否收藏
    2、单词拼写
    3、单词定义
*/
struct EnglishWord
{
    int isFavorite;
    char word[MAX_WORD_LENGTH];
    char definition[MAX_DEFINITION_LENGTH];
};

二、主函数功能逻辑

包含一个主循环,该循环持续显示菜单并等待用户输入。根据用户的选择,程序将执行相应的操作,如查单词、背单词或退出系统。在选择查询单词时,程序还包含一个嵌套循环,允许用户连续查询单词直到选择退出。程序会持续运行,直到用户选择退出系统。

c 复制代码
/* 主函数*/
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;
}
  1. 主循环: 主函数采用了一个无限循环 while (1),使得用户可以在执行完一次操作后选择继续进行其他操作或退出系统。
  2. 菜单显示和选择: 主循环内部通过 printf 显示简单的菜单,包括查单词、背单词、退出系统的选项。使用 scanf 获取用户的选择,并通过 switch 语句根据用户的选择执行相应的操作。
  3. 操作执行: switch 语句中根据用户的选择,执行相应的操作。如果用户选择查单词,则进入嵌套循环,调用 searchWord 函数实现连续查询。如果用户选择背单词,则调用 memorizeWord 函数执行背单词操作。如果用户选择退出系统,则输出退出信息并调用 exit(0) 退出程序。
    1. 查单词操作: 在选择查单词时,通过嵌套循环实现连续查询。用户可以在一次查询结束后选择是否继续查询,通过输入 'y' 或 'n' 决定。内部调用 searchWord 函数进行查询,保留用户的选择状态。
    2. 背单词操作: 在选择背单词时,调用 memorizeWord 函数执行背单词操作。用户在背单词的过程中可以通过按下任意键继续背下一个单词,包括 Enter 键。通过嵌套循环和非阻塞键盘输入的方式实现。
    3. 退出系统操作: 在选择退出系统时,输出退出信息并调用 exit(0) 退出程序,结束主循环。

三、查单词函数

这C语言函数用于在给定的文件中搜索指定的英文单词。
英语单词文件已进行资源绑定,可以在我的资源中进行查看。

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);
}
  1. 函数声明:

    c 复制代码
    void searchWord(const char *filename);
  2. 参数:

    • filename: 包含英文单词及其解释的文件名。
  3. 局部变量和结构体定义

    c 复制代码
    FILE *file;
    int flag = 0;
    char searchWord[MAX_WORD_LENGTH];
    struct EnglishWord currentWord;
    • file: 文件指针,用于打开和读取文件。
    • flag: 用于标记是否找到匹配的英文单词。
    • searchWord: 存储用户输入的待查找的英文单词。
    • currentWord: 结构体,包含英文单词和对应的解释。
  4. 文件打开检查:

    c 复制代码
    if ((file = fopen(filename, "r")) == NULL)
    {
        printf("无法打开文件 %s\n", filename);
        return;
    }
    • 检查文件是否成功打开,如果未成功,则输出错误信息并返回。
  5. 用户输入待查找的英文单词:

    c 复制代码
    printf("请输入待查找的英文单词(小写): ");
    scanf("%s", searchWord);
    • 提示用户输入待查找的英文单词。
  6. 遍历文件并比较英文单词:

    c 复制代码
    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。
  7. 输出结果:

    c 复制代码
    if (0 == flag)
    {
        printf("未找到英文单词:%s\n", searchWord);
    }
    • 如果未找到匹配的英文单词,输出相应提示。
  8. 关闭文件:

    c 复制代码
    fclose(file);
    • 关闭打开的文件,以防止内存泄漏

四、背单词函数

通过逐个从文件中读取英文单词及其解释,使用户能够逐个记忆这些单词,并且能够读取上次结束的位置。
英语单词文件已进行资源绑定,可以在我的资源中进行查看。

c 复制代码
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);
}
  1. 打开文件:

    • 函数接受一个文件名作为参数,并尝试以只读模式打开该文件。
    • 如果文件打开失败,函数打印错误消息并返回。
    c 复制代码
    if ((file = fopen(filename, "r")) == NULL)
    {
        printf("无法打开文件 %s\n", filename);
        return;
    }
  2. 获取上次读取的位置:

    • 函数尝试打开名为 "position_record.txt" 的记录文件,该文件保存上次读取的文件位置。
    • 如果记录文件打开失败,函数打印错误消息并返回。
    • 如果成功打开记录文件,函数读取上次读取的文件位置,并将文件指针移到该位置。
    c 复制代码
    if ((recordFile = fopen("position_record.txt", "r")) == NULL)
    {
        printf("单词位置记录失败!");
        return;
    }
    else
    {
        fscanf(recordFile, "%ld", &lastPosition);
        fclose(recordFile);
    
        fseek(file, lastPosition, SEEK_SET);
    }
  3. 逐个输入单词:

    • 使用循环从文件中逐个读取英文单词及其解释,存储在结构体 struct EnglishWord 中。
    • 在每个单词显示后,程序提示用户按任意键继续或按 'q' 键退出。
    • 用户按 'q' 键退出时,循环终止。
    c 复制代码
    while (fscanf(file, "%s %[^\n]", currentWord.word, currentWord.definition) != EOF)
    {
        // ... (显示单词,等待用户输入)
        if (ch == 'q') { break; }
        // ... (保存当前读取位置)
    }
  4. 记录当前读取位置:

    • 在每次成功读取一个单词后,将当前文件指针位置保存到 "position_record.txt" 文件中,以便下一次程序运行时能够从上次中断的位置继续读取。
    c 复制代码
    lastPosition = ftell(file);
    if ((recordFile = fopen("position_record.txt", "w")) == NULL)
    {
        printf("单词位置记录失败!");
    }
    else
    {
        fprintf(recordFile, "%ld", lastPosition);
        fclose(recordFile);
    }
  5. 关闭文件:

    • 最后关闭打开的文件。
    c 复制代码
    fclose(file);

五、补充

  • 完整程序

    c 复制代码
    /* 相关头文件 */
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <ctype.h>
    
    /* 单词最大长度 和 单词定义最大长度 */
    #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);
    }
相关推荐
励志成为嵌入式工程师3 小时前
c语言简单编程练习9
c语言·开发语言·算法·vim
Peter_chq3 小时前
【操作系统】基于环形队列的生产消费模型
linux·c语言·开发语言·c++·后端
hikktn5 小时前
如何在 Rust 中实现内存安全:与 C/C++ 的对比分析
c语言·安全·rust
观音山保我别报错5 小时前
C语言扫雷小游戏
c语言·开发语言·算法
小林熬夜学编程8 小时前
【Linux系统编程】第四十一弹---线程深度解析:从地址空间到多线程实践
linux·c语言·开发语言·c++·算法
墨墨祺8 小时前
嵌入式之C语言(基础篇)
c语言·开发语言
躺不平的理查德8 小时前
数据结构-链表【chapter1】【c语言版】
c语言·开发语言·数据结构·链表·visual studio
幼儿园园霸柒柒9 小时前
第七章: 7.3求一个3*3的整型矩阵对角线元素之和
c语言·c++·算法·矩阵·c#·1024程序员节
好想有猫猫9 小时前
【51单片机】串口通信原理 + 使用
c语言·单片机·嵌入式硬件·51单片机·1024程序员节
摆烂小白敲代码10 小时前
背包九讲——背包问题求方案数
c语言·c++·算法·背包问题·背包问题求方案数