C语言链表实现通讯录

基于链表实现通讯录

功能

  • 增加联系人
  • 删除联系人
  • 查找联系人
  • 保存通讯录到指定磁盘
  • 读取存在磁盘的通讯录信息

学过链表还是较容易看懂

代码如下

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define path "D:\\adbook.txt"
//通讯录文件存储位置选择

typedef struct node
{
    char name[20];
    char number[20];
    char job[20];
    struct node *next;
} Node;
//通讯录链表的节点结构:名字,号码,工作(由于号码只考虑看,用字符串省空间

Node *InitList()
{
    Node *head;
    head = (Node *)malloc(sizeof(Node));
    head->next = NULL;
    return head;
}
//初始化通讯录链表的根节点

void enter(Node *head, int *length);
//录入:1;若无提示则提示并询问
void del(Node *head, int *length);
//删除:2;查询到,回车删除
void list(Node *head);
//显示:3;显示通讯录
void search(Node *head);
//查询:4;输入名字在,存在则显示
void save(Node *head, int *sign);
//保存:5;进入保存界面,按回车保存,数据输入文件,显示Saveing file
void load(Node *head, int *length, int *sign);
//加载:6;将数据从磁盘加载到链表中

void create_file()
{
    FILE *fp;
    fp = fopen(path, "a");
    fclose(fp);
}
/*
定义一个函数创建空的txt文件,因为在load函数那使用fopen的r读取。
若采用a/a+或w/w+等,会导致读进乱码。
所以load只负责读取,另外创建一个create函数负责保证文件存在
*/
int main()
{
    Node *head;
    head = InitList();//初始化链表头
    create_file();
    int length = 0;//在插入联系人时需要用到长度信息
    int sign = 0;//用于标记本次运行是否读取磁盘(是否使用load函数),来选择不同的存储方式,在save处解释
    char key;//为什么不用int型,因为int如果输入其他非数字的东西,会死循环(害怕运行者刁难)
              //但带来的问题就是要处理scanf缓冲区数据的问题
    char ch;  //用于清楚缓冲区数据
    do
    {
        printf("\n");
        printf("\t\t\t\t*=================================*\n");
        printf("\t\t\t\t*                                 *\n");
        printf("\t\t\t\t*        欢迎使用清河通讯录!     *\n");
        printf("\t\t\t\t*                                 *\n");
        printf("\t\t\t\t|==================================|\n");
        printf("\t\t\t\t|       1--录入联系人信息          |\n");
        printf("\t\t\t\t|       2--删除联系人信息          |\n");
        printf("\t\t\t\t|       3--显示通讯录信息          |\n");
        printf("\t\t\t\t|       4--查询联系人信息          |\n");
        printf("\t\t\t\t|       5--保存联系人信息          |\n");
        printf("\t\t\t\t|       6--加载通讯录信息          |\n");
        printf("\t\t\t\t|       0--退出                    |\n");
        printf("\t\t\t\t|==================================|\n");
        printf("\t\t\t\t         请输入你的选项:");
        scanf("%c", &key);
        while ((ch = getchar()) != EOF && ch != '\n')
            ; //清除缓冲区的内容
        switch (key)
        {
        case '0':
            printf("\n");
            printf("\t\t\t\t*==================================*\n");
            printf("\t\t\t\t*                        		   *\n");
            printf("\t\t\t\t*      		   Bye Bye  	       *\n");
            printf("\t\t\t\t*                        		   *\n");
            printf("\t\t\t\t*==================================*\n");
            printf("\n");
            break;
        case '1':
            enter(head, &length);
            break;
        case '2':
            del(head, &length);
            break;
        case '3':
            list(head);
            break;
        case '4':
            search(head);
            break;
        case '5':
            save(head, &sign);
            break;
        case '6':
            load(head, &length, &sign);
            break;
        default:
            printf("\n\t\t\t\t   !!!请重新选择正确的选项!!!");
        }
    } while (key != '0');
    return 0;
}

void enter(Node *head, int *length)
{
    Node *node, *end;
    end = head;
    node = (Node *)malloc(sizeof(Node));
    if (head->next == NULL)
    {
        printf("\n");
        printf("\t\t\t\t*==================================*\n");
        printf("\t\t\t\t*                                  *\n");
        printf("\t\t\t\t*            通讯录为空。          *\n");
        printf("\t\t\t\t*                                  *\n");
        printf("\t\t\t\t*        是否需要添加新的联系人    *\n");
        printf("\t\t\t\t*         0.是       1.否          *\n");
        printf("\t\t\t\t*==================================*\n");
        printf("\n");
        printf("\t\t\t\t         请输入你的选项:");
        int count = 0;
        scanf("%d", &count);
        if (!count)
        {
            printf("\n");
            printf("\t\t\t\t*==================================*\n");
            printf("\t\t\t\t* 请输入:名字 号码 工作:         *\n");
            printf("\t\t\t\t*     注:三者之间请空格隔开       *\n");
            printf("\t\t\t\t*                                  *\n");
            printf("\t\t\t\t*==================================*\n");
            printf("\n");
            printf("\t\t\t\t 请输入相关信息:");
            scanf("%s%s%s", node->name, node->number, node->job);
            char c;
            c = getchar();
            end->next = node;
            node->next = NULL;
        }
    }
    else
    {
        printf("\n");
        printf("\t\t\t\t*==================================*\n");
        printf("\t\t\t\t* 请输入:名字 号码 工作:         *\n");
        printf("\t\t\t\t*     注:三者之间请空格隔开       *\n");
        printf("\t\t\t\t*                                  *\n");
        printf("\t\t\t\t*==================================*\n");
        printf("\n");
        printf("\t\t\t\t 请输入相关信息:");
        scanf("%s%s%s", node->name, node->number, node->job);
        for (int i = 0; i < *length; i++)
            end = end->next;
        end->next = node;
        node->next = NULL;
    }
    *length = *length + 1;
    printf("\n");
    printf("\t\t\t\t*==================================*\n");
    printf("\t\t\t\t*                                  *\n");
    printf("\t\t\t\t*         联系人成功已添加         *\n");
    printf("\t\t\t\t*                                  *\n");
    printf("\t\t\t\t*==================================*\n");
};

void del(Node *head, int *length)
{
    char del_name[100];
    printf("\n");
    printf("\t\t\t\t*==================================*\n");
    printf("\t\t\t\t*                                  *\n");
    printf("\t\t\t\t*     请输入要删除的联系人名字:   *\n");
    printf("\t\t\t\t*                                  *\n");
    printf("\t\t\t\t*==================================*\n");
    printf("\n");
    printf("\t\t\t\t*请输入相关信息:");
    scanf("%s", del_name);
    char c;
    c = getchar(); //这里需要用c“吃掉”scanf输入时的回车,避免影响之后的“确认”操作
    Node *node, *d_node;
    d_node = head->next;
    node = head;
    for (int i = 0; i < *length; i++)
    {
        if (strcmp(d_node->name, del_name) == 0)
        {
            printf("\n");
            printf("\t\t\t\t*==================================*\n");
            printf("\t\t\t\t*                                  *\n");
            printf("\t\t\t\t*     您确定要删除此人吗?          *\n");
            printf("\t\t\t\t*     点击 Enter 确定删除操作      *\n");
            printf("\t\t\t\t*     输入   b   取消删除操作      *\n");
            printf("\t\t\t\t*                                  *\n");
            printf("\t\t\t\t*==================================*\n");
            printf("\n");
            printf("\t\t\t\t*请输入相关信息:");
            c = getchar();
            if (c == '\n')
            {
                node->next = d_node->next;
                free(d_node);
                printf("\n");
                printf("\t\t\t\t*==================================*\n");
                printf("\t\t\t\t*                                  *\n");
                printf("\t\t\t\t*              删除成功            *\n");
                printf("\t\t\t\t*                                  *\n");
                printf("\t\t\t\t*==================================*\n");
                *length = *length - 1;
                return;
            }
            else
            {
                c = getchar();
                return;
            }
        }
        node = node->next;
        d_node = d_node->next;
    }
    printf("\n");
    printf("\t\t\t\t*==================================*\n");
    printf("\t\t\t\t*                                  *\n");
    printf("\t\t\t\t*              查无此人            *\n");
    printf("\t\t\t\t*                                  *\n");
    printf("\t\t\t\t*==================================*\n");
};

void list(Node *head)
{
    if (head->next == NULL)
    {
        printf("\n");
        printf("\t\t\t\t*==================================*\n");
        printf("\t\t\t\t*                                  *\n");
        printf("\t\t\t\t*            通讯录为空            *\n");
        printf("\t\t\t\t*                                  *\n");
        printf("\t\t\t\t*==================================*\n");
    }
    else
    {
        printf("\n");
        printf("\t\t\t\t*==================================*\n");
        printf("\t\t\t\t*姓名        电话       工作       *\n");
        while (head->next != NULL)
        {
            head = head->next;
            printf("\t\t\t\t %-12s %-10s %s\n", head->name, head->number, head->job);
        }
        printf("\t\t\t\t*==================================*\n");
    }
};

void search(Node *head)
{
    Node *node;
    node = head->next;
    printf("\n");
    printf("\t\t\t\t*==================================*\n");
    printf("\t\t\t\t*                                  *\n");
    printf("\t\t\t\t*        请输入要查找的名字        *\n");
    printf("\t\t\t\t*                                  *\n");
    printf("\t\t\t\t*==================================*\n");
    printf("\n");
    printf("\t\t\t\t*请输入相关信息:");
    char s_name[100];
    scanf("%s", s_name);
    while (node)
    {
        if (strcmp(node->name, s_name) == 0)
        {
            printf("\n");
            printf("\t\t\t\t*==================================*\n");
            printf("\t\t\t\t*                                  *\n");
            printf("\t\t\t\t %-12s %-10s %s", node->name, node->number, node->job);
            printf("\t\t\t\t*                                  *\n");
            printf("\t\t\t\t*==================================*\n");
            return;
        }
        node = node->next;
    }
    printf("\n");
    printf("\t\t\t\t*==================================*\n");
    printf("\t\t\t\t*                                  *\n");
    printf("\t\t\t\t*              查无此人            *\n");
    printf("\t\t\t\t*                                  *\n");
    printf("\t\t\t\t*==================================*\n");
};
void save(Node *head, int *sign)
{
    Node *node;
    node = head->next;
    FILE *fp;
    if (*sign)
    {
        fp = fopen(path, "w");
    }
    else
    {
        fp = fopen(path, "a");
    }
    while (node)
    {
        fprintf(fp, "%s %s %s%s", node->name, node->number, node->job, "\n");
        node = node->next;
    }
    fclose(fp);
    printf("\n");
    printf("\t\t\t\t*==================================*\n");
    printf("\t\t\t\t*                                  *\n");
    printf("\t\t\t\t*          数据已保存到磁盘        *\n");
    printf("\t\t\t\t*                                  *\n");
    printf("\t\t\t\t*==================================*\n");
};

void load(Node *head, int *length, int *sign)
{

    FILE *fp = NULL;
    fp = fopen(path, "r");

    Node *node, *end;
    end = head;
    for (int i = 0; i < *length; i++)
        end = end->next;
    while (1)
    {
        if (feof(fp))
            break;
        node = (Node *)malloc(sizeof(Node));
        memset(node, '\0', sizeof(Node));
        fscanf(fp, "%s %s %s\n", node->name, node->number, node->job);
        if (strlen(node->name) == 0)
            break;
        node->next = end->next;
        end->next = node;
        end = node;
        *length = *length + 1;
    };
    end->next = NULL;
    fclose(fp);
    printf("\n");
    printf("\t\t\t\t*==================================*\n");
    printf("\t\t\t\t*                                  *\n");
    printf("\t\t\t\t*         磁盘内容加载完毕         *\n");
    printf("\t\t\t\t*                                  *\n");
    printf("\t\t\t\t*==================================*\n");
    *sign = 1;
};
posted @ 2022-04-09 17:35  ace_fjll  阅读(318)  评论(0)    收藏  举报