系统编程IO操作 之 电子词典

前言

  • gcc elecdict.c -o dict生成可执行文件dict
  • 然后执行这个文件,使用如下图所示:
    在这里插入图片描述

使用说明

完成上图操作需要两个文件,一个是源代码elecdict.c,一个是单词本dict.txt;这两个文件都放在下面了,源代码elecdict.c可以直接复制粘贴,单词本dict.txt内容有8万多行,就专门上传到csdn了,可以点击免费下载

源代码elecdict.c

#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<string.h>
#include<errno.h>

/**
 * 节点定义:存储单词和翻译
 * 用链表实现
 */
typedef struct Node {
    char *word;
    char *trans;
    struct Node *next;
} Node;

/**
 * 1.加载单词文件到内存:
 * 打开文件用fopen()
 * 遍历文件用fgets()
 * 关闭文件用fclose()
 */
Node *loadDict(char *filename){
    FILE *fp = fopen(filename,"r");
    if (fp == NULL) {
        return NULL;
    }

    char buff[1024] = {0};
    Node *head = NULL;
    while(fgets(buff, sizeof(buff),fp)) {
        Node *node = (Node *)malloc(sizeof(Node));

        node->word = (char *)malloc(sizeof(char) * strlen(buff));
        strcpy(node->word, buff + 1);
        node->word[strlen(node->word) - 1] = '\0';

        fgets(buff, sizeof(buff), fp);
        node->trans = (char *)malloc(sizeof(char) * strlen(buff));
        strcpy(node->trans, buff + 6);
        node->trans[strlen(node->trans) - 1] = '\0';

        node->next = head;
        head = node;
    }    
    fclose(fp);
    return head;
}

//1.1测试:用于测试加载单词文件到node是否成功
void test(Node *head) {
    int cnt = 1;
    while (head && cnt <= 100) {
        printf("cnt = [%d] word = [%s] trans = [%s]\n", cnt++, head->word, head->trans);
        head = head->next;
    }
}

/**
 * 2.1在node中查找单词:
 */ 
Node *findNode(Node *head, char *word) {
    while (head && strcmp(word, head->word)) {
        head = head->next;
    }
    return head;
}

/**
 * 2.2格式化输出翻译:
 * 使用strtok来截断各词性
 */ 
void splitTrans(char *trans) {
    printf("翻译 :\n");
    char *buff = (char *)malloc(sizeof(char) * (strlen(trans) + 1));
    strcpy(buff, trans);
    char *token = strtok(buff, "@");
    while (token) {
        /* 字体颜色代码:30-37
         * 30:黑  31:红   32:绿 33:黄   34:蓝色 35:紫色 36:深绿 37:白色
         * 背景颜色代码:40-47
         * 40:黑  41:深红 42:绿 43:黄色 44:蓝色 45:紫色 46:深绿 47:白色
         */
        printf("\033[31;47m%s\033[0m\n", token);
        token = strtok(NULL, "@");
    }
    free(buff);
    return ;
}
/**
 * 2.查找单词:
 */ 
void findWord(Node *head) {
    char inwd[50];
    while(1) {
        printf("请输入一个单词:or 退出程序q!\n");
        scanf("%s",inwd);
        if (!strcmp(inwd, "q!")) {
            break;
        }
        Node *fd = findNode(head,inwd);
        if (fd) {
            //printf("翻译 :\n %s\n", fd->trans);
            splitTrans(fd->trans);
        } else {
            printf("没有找到!\n");
        }
    }
    printf("再见!\n");
    return ;
}

//3.释放内存,关闭词典
void freeDict(Node *head) {
    Node *temp;
    while (head) {
        temp = head;
        head = head->next;
        free(temp->word);
        free(temp->trans);
        free(temp);
    }
    return ;
}

int main() {
    Node *node;
    char filename[1024] = "dict.txt";
    //1.把词典文件加载到内存
    node = loadDict(filename);
    if (node == NULL) {
        perror("loadDict");
        printf("注意:加载的单词文件不存在\n");
        exit(1);
    }
    //1.1测试:用于测试加载单词文件到node是否成功
    //test(node);

    //2.启动词典,支持反复查询
    findWord(node);
    
    //3.释放内存,关闭词典
    freeDict(node);

    return 0;
}

单词文件dict.txt

在这里插入图片描述
单词本dict.txt内容有8万多行,就专门上传到csdn了,可以点击免费下载

#a
Trans:art. 一;字母A
#a.m.
Trans:n. 上午
#a/c
Trans:n. 往来帐户@往来:come - and - go; contact; intercourse@n. 往来帐户
#aardvark
Trans:n. 土猪
#aardwolf
Trans:n. 土狼
#aasvogel
Trans:n. 秃鹰之一种
#abaci
Trans:n. 算盘
#aback
Trans:ad. 向后地;朝后地
#abacus
Trans:n. 算盘
#abaft
Trans:ad. 向船尾@prep. 在...后
#abalone
Trans:n. 鲍鱼
#abandon
Trans:vt. 放弃;沉溺@n. 放任

源码解析

实现思路就三步:

  1. 把词典文件加载到内存
  2. 启动词典支持反复查询
  3. 释放内存关闭词典

1. 把词典文件加载到内存

  • 源码中使用链表存储单词和翻译
/**
 * 节点定义:存储单词和翻译
 * 用链表实现
 */
typedef struct Node {
    char *word;
    char *trans;
    struct Node *next;
} Node;
  • 加载文件流程
    在这里插入图片描述
/**
 * 1.加载单词文件到内存:
 * 打开文件用fopen()
 * 遍历文件用fgets()
 * 关闭文件用fclose()
 */
Node *loadDict(char *filename){
    FILE *fp = fopen(filename,"r");
    if (fp == NULL) {
        return NULL;
    }

    char buff[1024] = {0};
    Node *head = NULL;
    while(fgets(buff, sizeof(buff),fp)) {
        Node *node = (Node *)malloc(sizeof(Node));

        node->word = (char *)malloc(sizeof(char) * strlen(buff));
        strcpy(node->word, buff + 1);
        node->word[strlen(node->word) - 1] = '\0';

        fgets(buff, sizeof(buff), fp);
        node->trans = (char *)malloc(sizeof(char) * strlen(buff));
        strcpy(node->trans, buff + 6);
        node->trans[strlen(node->trans) - 1] = '\0';

        node->next = head;
        head = node;
    }    
    fclose(fp);
    return head;
}

2. 启动词典支持反复查询

  1. 启动词典之后的提示信息
  2. 输入单词后的输出
    单词?是否存在,是否是词典文件中的单词?
    如果是?如果不是?
  3. 怎样表示退出?q!表示退出
    在这里插入图片描述

3. 释放内存关闭词典

//3.释放内存,关闭词典
void freeDict(Node *head) {
    Node *temp;
    while (head) {
        temp = head;
        head = head->next;
        free(temp->word);
        free(temp->trans);
        free(temp);
    }
    return ;
}

后记

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

杰之行

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值