链表实验-文件读取-增删改查

#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <string.h>
//========================================================结构体===========================================================
//字符类型节点
typedef struct Node
{
    char *data;        //字符型指针
    struct Node *next; //指向同类型节点的指针
} NODE, *PNODE;

//字符串链表
typedef struct LinkedList
{
    PNODE head; //头节点
    int length; //链表长度
} LINKEDLIST, *PLINKLIST;
//========================================================函数列表===========================================================
void appendNode(PLINKLIST list, char *value);            //尾部追加节点
void headAddNode(PLINKLIST list, char *value);           //头部插入节点
void insertNode(PLINKLIST list, char *value, int index); //任意位置插入节点
void delAll(PLINKLIST list);                             //清空链表
void delNodeByIndex(PLINKLIST list, int index);          //删除指定下标的节点
PNODE findNodeByIndex(PLINKLIST list, int index);        //根据下标查找并返回节点
void readFile(PLINKLIST list, char *filePath);           //载入文件
void opration(PLINKLIST list);                           //循环操作
void outPutAllList(PLINKLIST list);                      //输出链表所有
void findData(PLINKLIST list);                           //查找
void insertData(PLINKLIST list);                         //插入
void delData(PLINKLIST list);                            //删除
void findEnglish(PLINKLIST list);                        //英文精确查找
void findChinese(PLINKLIST list);                        //中文模糊查找
void getWord(char *data, char *result, int options);     //获取,英文,词型,中文三种字符串的函数
int cmp(char *str, char *find);                          //判断str字符串中是否包含find字符串
int cmpAll(char *str, char *find);                       //全词匹配
//========================================================主函数============================================================
void main()
{
    PLINKLIST list = (PLINKLIST)malloc(sizeof(LINKEDLIST)); //创建链表
    list->length = 0;
    list->head = NULL;
    readFile(list, "cet4word2.txt"); //加载数据
    opration(list);                  //循环测试
    alert(6);                        //佛祖保佑,永无bug
}
//========================================================WORD-CRUD=========================================================
/*
    功能:载入文件
    参数: filePath 文件路径
    返回值:无
*/
void readFile(PLINKLIST list, char *filePath)
{
    char buf[1024];
    //打开文件输入流
    FILE *fp = fopen(filePath, "r");

    //校验文件是否打开成功
    if (fp == NULL)
    {
        printf("文件打开失败");
        return;
    }

    //将流写入数组中
    while (!feof(fp)) //如果文件没有结束,那么就持续循环
    {
        //读取一行到buf中
        //申请空间

        if (NULL != fgets(buf, 1024, fp))
        {
            //将数据追加到链表中
            appendNode(list, buf);
        }
    }
    //关闭文件输入流
    fclose(fp);
    alert(1);
}
/*
    功能:循环测试个模块功能
    参数: list 链表
    返回值:无
*/
void opration(PLINKLIST list)
{
    _flushall(); //以防万一,清除一下流
    char op;     //输入的操作
    //输出一些操作前的提示
    alert(5);
    alert(6);
    alert(3);
    //循环操作,输入操作类型
    while (1)
    {
        printf("请输入您的操作:");
        _flushall();
        op = getchar();
        if (op == '0' || op == '1' || op == '2' || op == '3' || op == '4' || op == '5')
        {
            if (op == '0')
            {
                printf("退出成功\n");
                return;
            }
            break;
        }
        else
        {
            printf("您的输入有误\n");
        }
    }
    //循环操作,执行操作的函数
    while (op != '0')
    {
        switch (op)
        {
        case '1':
            outPutAllList(list);
            break;
        case '2':
            findData(list); //暂时不可用
            break;
        case '3':
            insertData(list);
            break;
        case '4':
            delData(list);
            break;
        default:
            printf("请输入合法字符\n");
            break;
        }

        printf("请继续您的操作:");
        _flushall();
        op = getchar();
        if (op == '0')
        {
            printf("退出成功\n");
        }
    }
}
/*
    功能:输入链表所有信息
    参数:
        list 链表
    返回值:
        无
*/
void outPutAllList(PLINKLIST list)
{
    int i = 1;
    PNODE temp = list->head;
    while (temp != NULL)
    {
        printf("第 %d 个的内容是   %s \n", i, temp->data);
        temp = temp->next;
        i++;
    }
}
/*
    功能:英文精确查找,中文模糊查找
    参数:无
    返回值:无
    思路:
        分两种情况:1、英文查找 2、中文查找
*/
void findData(PLINKLIST list)
{
    _flushall(); //以防万一,清除一下流
    alert(4);
    char op; //输入的操作
    //循环操作,输入操作类型
    while (1)
    {
        printf("请输入您的操作:");
        _flushall();
        op = getchar();
        if (op == '0' || op == '1' || op == '2')
        {
            if (op == '0')
            {
                alert(3);
                return;
            }
            break;
        }
        else
        {
            printf("您的输入有误\n");
        }
    }
    //循环操作,执行操作的函数
    while (op != '0')
    {
        switch (op)
        {
        case '1':
            findEnglish(list); //英文查找
            break;
        case '2':
            findChinese(list); //中文查找
            break;
        default:
            printf("请输入合法字符\n");
            break;
        }
        printf("请输入您的操作:");
        _flushall();
        op = getchar();
        if (op == '0')
        {
            alert(3);
        }
    }
}
/*
    功能:英文精确查找
    参数:
        list
    返回值:
        无
    思路:
        输入一个要查找的英文字符串,value
        循环执行           
            对list中的某个data进行剪切,遇见第一个逗号就停止,然后将第一个逗号之前的字符串保存到一个字符数组中叫 A
            用strstr函数对比 a和value 如果一样 就打印当前 data 并结束这个函数


*/
void findEnglish(PLINKLIST list)
{
    char value[100];
    char *english = (char *)malloc(sizeof(char) * 1000);
    printf("请输入要查询的内容:");
    scanf("%s", value);
    PNODE tempNode = list->head;
    while (tempNode != NULL)
    {
        getWord(tempNode->data, english, 1);
        if (cmpAll(english, value)) //精确查找
        {
            printf("查找成功,内容为:%s\n", tempNode->data);
            return;
        }
        tempNode = tempNode->next;
    }
    printf("未搜寻到结果\n");
}
/*
    功能:中文模糊查找
    参数:
        list
    返回值:
        无
*/
void findChinese(PLINKLIST list)
{
    char value[100];
    char *chinese = (char *)malloc(sizeof(char) * 1000);
    printf("请输入要查询的内容:");
    scanf("%s", value);
    PNODE tempNode = list->head;

    while (tempNode != NULL)
    {
        getWord(tempNode->data, chinese, 3);
        if (cmp(chinese, value)) //模糊查找
        {
            printf("查找成功,内容为:%s\n", tempNode->data);
        }
        tempNode = tempNode->next;
    }
}
/*
    功能:获取英文单词
    参数:
        char *data 输入值
        result 返回值
        int 返回值类型 1、英文 2、词性 3、翻译

*/
void getWord(char *data, char *result, int options)
{
    int pos = 0;
    int j = 0;
    for (int i = 0; i < 1000; i++)
    {
        if (options == 1) //英文
        {

            if (data[i] == ',') //输入数据碰见第一个“,”结束循环,此时result中是英文
            {
                result[i] = '\0';
                return;
            }

            result[i] = data[i]; //一个字符一个字符的将数据切割
        }
        else if (options == 2) //词性
        {
            if (data[i] == ',')
            {
                pos++;
                i++; //跳过“,”
            }
            if (pos == 1) //从第一个“,”开始之后赋值
            {
                result[j] = data[i]; //加1就是跳过,号
                j++;
            }
            if (pos == 2) //遇见第二个“,”此时的result是词型
            {
                result[j] = '\0';
                return;
            }
        }
        else
        {
            if (data[i] == ',')
            {
                pos++;
                i++; //跳过“,”
            }
            if (pos == 2) //从第二个“,”开始之后赋值
            {
                char temp;
                int k = i; //也不知道为啥i的步长变成了2,所以这里新开辟一个空间k
                while (1)
                {
                    result[j] = data[k]; //赋值
                    temp = data[k];
                    k++;
                    j++;
                    if (temp == '\0') //字符串结束
                    {
                        return;
                    }
                }
            }
        }
    }
}
/*
    功能:插入元素
    参数:无
    返回值:无
*/
void insertData(PLINKLIST list)
{
    int pos;          //插入的位置
    char value[1024]; //插入的数据
    printf("请输入您将要插入的数据:");
    scanf("%s", &value);
    printf("请输入您要插入的位置:");
    scanf("%d", &pos);
    //插入之前判断一下是否可以插入
    while (1)
    {
        if (pos < 1 || pos > (list->length + 1))
        {
            printf("插入的位置不合理,请重新输入位置:");

            scanf("%d", &pos);
        }
        else
        {
            break;
        }
    }
    //开始插入
    insertNode(list, value, pos - 1);
    printf("插入成功\n");
}
/*
    功能:删除某个节点
    参数:无
    返回值:无
*/
void delData(PLINKLIST list)
{
    int pos; //删除的位置
    printf("请输入您要删除的位置:");
    scanf("%d", &pos);
    while (1)
    {
        if (pos < 1 || pos > list->length)
        {
            printf("删除的位置不合理,请重新输入位置:");
            scanf("%d", &pos);
        }
        else
        {
            break;
        }
    }
    delNodeByIndex(list, pos - 1);
    printf("删除成功\n");
}
//========================================================链表添加===========================================================
/*
    功能:尾部追加
    参数:
        list 链表
        value 要追加的元素
    返回值:
        无
    原理:
        两种情况:1、空链表2、非空链表
        1、空链表:将值赋给头节点 length++
        2、非空链表:
            例如 a b c 三个节点,现在将temp节点插入到尾部
            c->next = temp length++
            关键是获取到最后一个节点

*/
void appendNode(PLINKLIST list, char *value)
{
    PNODE tempNode = (PNODE)malloc(sizeof(NODE)); //为新加的节点申请空间
    char *newData = (char *)malloc(1024);         //新开辟一块空间去放数据
    tempNode->data = strcpy(newData, value);
    tempNode->next = NULL;
    //判断是否是空链表
    //空链表
    if (list->length == 0)
    {
        list->head = tempNode; //赋值给头部节点
        list->length++;
    }
    //非空链表
    else
    {
        findNodeByIndex(list, list->length - 1)->next = tempNode; //尾部节点指向新加的节点
        list->length++;
    }
}
/*
    功能:头部追加
    参数:
        list 链表
        value 追加的值
    返回值:
        无
    原理:
        两种情况:1、空链表2、非空链表
        1、空链表:将值赋给头节点 length++
        2、非空链表:
            例如 a b c 三个节点,现在将temp节点插入到头部
            temp->next = list->head
            list->head = temp
*/
void headAddNode(PLINKLIST list, char *value)
{
    PNODE tempNode = (PNODE)malloc(sizeof(NODE)); //为新加的节点申请空间
    char *newData = (char *)malloc(1024);         //新开辟一块空间去放数据
    tempNode->data = strcpy(newData, value);
    tempNode->next = NULL;
    //判断是否是空链表
    //空链表
    if (list->length == 0)
    {
        list->head = tempNode; //赋值给头部节点
        list->length++;
    }
    //非空链表
    else
    {

        tempNode->next = list->head; //新节点指向头节点
        list->head = tempNode;       //头节点重新命名为head
        list->length++;
    }
}
/*
    功能:插入数据
    参数: 
        list 链表
        value  插入的值
        index  插入的下标
    返回值:
        无
    原理:
        三种情况:1、位置在头部2、位置在中间3、末尾
        1、直接调用headAdd()
        2、假设有 a b c 三个节点 现在有一个temp节点要插入到位置2,即插入后的顺序是 a temp b c
        temp->next = a->next
        a->next = temp
        关键是要找到节点a,即要插入位置的前一个节点
*/
void insertNode(PLINKLIST list, char *value, int index)
{
    if (index < 0 || index > list->length)
    {
        printf("插入位置不合理");
        return;
    }
    PNODE tempNode = (PNODE)malloc(sizeof(NODE));
    char *newData = (char *)malloc(1024); //新开辟一块空间去放数据
    tempNode->data = strcpy(newData, value);
    tempNode->next = NULL;
    if (index == 0)
    {
        headAddNode(list, value); //头加
        list->length++;
    }
    else if (index == list->length)
    {
        appendNode(list, value);
    }
    else
    {
        tempNode->next = findNodeByIndex(list, index - 1)->next;
        findNodeByIndex(list, index - 1)->next = tempNode;
        list->length++;
    }
}
//========================================================链表删除===========================================================
/*
    功能:清空链表
    参数:
        list 要清空的链表
    返回值:
        无
    原理:
        循环free
*/
void delAll(PLINKLIST list)
{
    list->length = 0;
    while (list->head != NULL)
    {
        PNODE tempNode = list->head;
        list->head = list->head->next;
        free(tempNode);
    }
}
/*
    功能:删除指定下标的节点
    参数:
        list 链表
        index 要删除节点的下标
    返回值:
        无
    原理:
        两种情况:1、头部节点 2、尾部节点
        1、头部节点 例如有 a b c 现在要删除a
            temp = list-head 将头部节点存储
            list->head = list->head->next 将头部变成第二个元素
            temp->next = NULL a断开和b的连接
            free(temp)
        2、中间节点 例如有 a b c 现在要删除b
            temp = a->next
            a->next = a->next->next a的下一个节点指向c 但是b现在也指向了c,所以还得操作一波
            temp->next = NULL b指向空 

*/
void delNodeByIndex(PLINKLIST list, int index)
{
    //空链表判断
    if (list->length == 0)
    {
        printf("链表已空");
        return;
    }
    //位置判断
    if (index < 0 || index > list->length - 1)
    {
        printf("删除位置不合理");
        return;
    }
    //头节点删除
    if (index == 0)
    {
        PNODE tempNode = list->head;
        list->head = list->head->next;
        tempNode->next = NULL;
        list->length--;
        return;
    }
    //其他位置删除
    else
    {
        PNODE tempNode = findNodeByIndex(list, index - 1)->next;
        findNodeByIndex(list, index - 1)->next = findNodeByIndex(list, index - 1)->next->next;
        tempNode->next = NULL;
        list->length--;
    }
}
/*
    功能:删除并打印返回被删除的节点
    参数:
        index
        list
    返回值:
        无
*/
PNODE delNodeByIndexReturnNode(PLINKLIST list, int index)
{
    //空链表判断
    if (list->length == 0)
    {
        printf("链表已空");
        return;
    }
    //位置判断
    if (index < 0 || index > list->length - 1)
    {
        printf("删除位置不合理");
        return;
    }
    //头节点删除
    if (index == 0)
    {
        PNODE tempNode = list->head;
        list->head = list->head->next; //将第二个节点变成头节点
        tempNode->next = NULL;
        list->length--;
        return tempNode;
    }
    //其他位置删除
    else
    {
        PNODE tempNode = findNodeByIndex(list, index - 1)->next;
        findNodeByIndex(list, index - 1)->next = findNodeByIndex(list, index - 1)->next->next;
        tempNode->next = NULL;
        list->length--;
        return tempNode;
    }
}
//========================================================链表查找===========================================================
/*
    功能:根据下标获取节点
    参数:
        list 链表
        index 下标
    返回值:
        tempNode 对应下表的节点
*/
PNODE findNodeByIndex(PLINKLIST list, int index)
{
    PNODE tempNode = list->head; //将临时变量指向头节点
    if (list->length == 0)
    {
        printf("空链表\n");
        return;
    }
    if (index < 0 || index > (list->length - 1))
    {
        printf("下标不合理\n");
        return;
    }
    int j = 0; //下标
    while (tempNode != NULL)
    {
        if (index != j)
        {
            tempNode = tempNode->next;
            j++;
        }
        else
        {
            return tempNode;
        }
    }
}
//========================================================字符比较函数===========================================================
/*
    功能:中文模糊查找
    参数:
        str 被查找的字符串
        find 要查找的字符串
    返回值:
        0 str不包含find
        1 str包含find
    思路:
        这里一个中文字符有三个字节
        先获取str的length 和find的length
        校验
        if
            str.length<find.length  返回0
        else 
                这里的find要和str中的起始位置0,1,2分别比较才能确保包含在str中

                for(j=0;j<str.length-find.length;j++){外层循环循环str的位置
                    int k = 0;
                    for(i=0;i<find.length;i++){内层循环循环find的值,分别于str的值进行比较
                        if(find[i] == str[j]){
                            k++;
                            if(i==find.length){
                                return 1; 找到了
                            }
                            while (k != strlen(find))
                            {
                                if (find[i + k] == str[j + k])//当第一个字符匹配后,就开始比较后面字符是否一样
                                {
                                    k++;
                                    if (k == strlen(find))//全一样就说明包含
                                    {
                                        return 1;
                                    }
                                }
                                else
                                {
                                    k = 0; //k重新赋值为0
                                    break;
                                }
                            }
                        }
                    }
                        12345
                        345
                    
                }
                
*/
int cmp(char *str, char *find)
{
    if (strlen(find) > strlen(str))
    {
        return 0;
    }
    else
    {
        for (int j = 0; j < strlen(str); j++)
        {
            // printf("===========第 %d 次 循环==========\n", j);
            int k = 0;
            for (int i = 0; i < strlen(find); i++)
            {
                // printf("find[%d] == %d   str[%d] == %d\n", i, find[i], j, str[j]);
                if (find[i] == str[j])
                {
                    k++;
                    // printf("k----->%d\n", k);
                    if (k == strlen(find))
                    {
                        return 1;
                    }
                    while (k != strlen(find))
                    {
                        if (find[i + k] == str[j + k])
                        {
                            k++;
                            if (k == strlen(find))
                            {
                                return 1;
                            }
                        }
                        else
                        {
                            k = 0; //k重新赋值为0
                            break;
                        }
                    }
                }
            }
        }
        return 0;
    }
}
/*
    功能:英文精确查找
    参数:
        str 被查找的字符串
        find 要查找的字符串
    返回值:
        0 str != find
        1 str == find
    思路:

*/
int cmpAll(char *str, char *find)
{
    if (strlen(str) != strlen(find))
    {
        return 0;
    }
    else
    {
        int k = 0;
        for (int i = 0; i < strlen(str); i++)
        {
            if (find[i] == str[i])
            {
                k++;
                if (k == strlen(str))
                {
                    return 1;
                }
            }
            else
            {
                return 0;
            }
        }
    }
}
//========================================================提示信息===========================================================
/*
    功能:各种提示信息
    参数:options
    返回值:无
*/
void alert(int options)
{
    switch (options)
    {
    case 1:
        printf("-------------------------------------------------------------\n");

        printf("|                                                           |\n");

        printf("|                        词库数据装载成功                   |\n");

        printf("|                                                           |\n");

        printf("-------------------------------------------------------------\n");
        break;
    case 2:
        printf("-------------------------------------------------------------\n");

        printf("|                                                           |\n");

        printf("|                      暂无词库数据记录                     |\n");

        printf("|                                                           |\n");

        printf("-------------------------------------------------------------\n");
        break;
    case 3:
        printf("-------------------------------------------------------------\n");

        printf("|                                                           |\n");

        printf("|                           1.显示词库所有信息              |\n");

        printf("|                           2.查找单词                      |\n");

        printf("|                           3.插入单词                      |\n");

        printf("|                           4.删除单词                      |\n");

        printf("|                           0.退出系统                      |\n");

        printf("|                                                           |\n");

        printf("|                                                           |\n");

        printf("-------------------------------------------------------------\n");
        break;
    case 4:
        printf("-------------------------------------------------------------\n");

        printf("|                                                           |\n");

        printf("|                           1.英文全词匹配查找              |\n");

        printf("|                           2.中文模糊查找                  |\n");

        printf("|                           0.退出                          |\n");

        printf("|                                                           |\n");

        printf("-------------------------------------------------------------\n");
        break;
    case 5:
        printf("-------------------------------------------------------------\n");

        printf("|                        欢迎使用英汉辞典                   |\n");

        printf("-------------------------------------------------------------\n");
        break;
    case 6:
        printf("                              _ooOoo_                      \n");
        printf("                             o8888888o                      \n");
        printf("                             88 '.' 88                      \n");
        printf("                             (| -_- |)                      \n");
        printf("                             O\\  =  /O                      \n");
        printf("                          ____/`---'\\____                      \n");
        printf("                        .'  \\|     |//  `.                      \n");
        printf("                       /  \\|||  :  |||//  \\                      \n");
        printf("                      /  _||||| -:- |||||-  \\                      \n");
        printf("                      |   | \\\\  -  /// |   |                      \n");
        printf("                      | \\_|  ''\\---/''  |   |                      \n");
        printf("                      \\  .-\\__  `-`  ___/-. /                      \n");
        printf("                    ___`. .'  /--.--\\  `. . __                      \n");
        printf("                 .'' '<  `.___\\_<|>_/___.'  >'''.                      \n");
        printf("                | | :  `- \\`.;`\\ _ /`;.`/ - ` : | |                      \n");
        printf("                \\  \\ `-.   \\_ __\\ /__ _/   .-` /  /                      \n");
        printf("           ======`-.____`-.___\\_____/___.-`____.-'======                      \n");
        printf("                              `=---='                      \n");
        printf("           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^                      \n");
        printf("                    佛祖保佑       永无BUG                      \n");
        break;
    default:
        break;
    }
}

  • 5
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Antgeek

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

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

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

打赏作者

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

抵扣说明:

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

余额充值