通讯录(通过链表实现)

通讯录(通过链表实现)

设计并实现一个简易的通讯录软件,管理个人通讯记录。一条通讯记录可包括:
姓名、工作单位、手机、住宅电话、E-Mail、家庭住址等(可自行增删,但不可过少)。
该系统应实现以下基本功能:
(1)增加新的通讯记录。
(2)删除已有的通讯记录。
(3)修改已有的通讯记录。
(4)浏览全部或指定(如指定姓名、工作单位等)的通讯记录。
(5)合理组织排列各项功能,界面可使用键盘操作。
(6)以文件的形式存储数据。

样例1

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

 #include <stdio.h>
#include <stdlib.h>
#include <string.h>
char filename[10] = {"txl"};
FILE *fp;
struct ListNode {
    char name[30];
    char work[30];
    char tel[30];
    char addr[50];
    struct ListNode *next;
};

struct ListNode *createlist()       //通讯录的建立
{
    struct ListNode *head=NULL,*p,*last;
    int flag = 1;                   //用于判断是否结束联系人的输入
    last=head;
    while(flag){
        p=(struct ListNode*)malloc(sizeof(struct ListNode)); //申请新结点
        printf("名字\t工作单位\t电话\t地址\n");
        scanf("%s%s%s%s", p->name, p->work, p->tel, p->addr);
        p->next = NULL; //新结点为空,
        if(head == NULL)//若为头结点,则让head指向p
            head = p;
        else          //非头结点,则连接在上一个结点
            last->next = p;
        last = p;       //让last指向p,移动标志位到新结点
        printf("\n输入1继续输入新的联系人,输入0退出输入\n");
        scanf("%d", &flag);
    }
    return head;
}
void insertNode(ListNode *head,ListNode *p)     //插入联系人
{
    ListNode *p1, *p2;
    p1 = head;
    p2 = p1->next;
    while(p2 != NULL){
        p1 = p2;        //p1指向刚访问过的结点
        p2 = p2->next;  //p2指向表的下一个结点
    }
    p1->next = p;       //插入p所指向的结点
    p->next = p2;       //连接表中剩余部分
}
ListNode *listfind(ListNode *head)      //查找联系人
{
    ListNode *p;
    char temp[30];           //先存储要找的人 的名字
    printf("请输入名字查找\n");
    scanf("%s", temp);
    if(strcmp(head->name,temp) == 0)//如果通讯录第一个是要找的人直接返回头结点
        return head;
    p = head->next;          //如果不是第一个则往下找
    while(p && strcmp(p->name,temp) != 0){//如果没找完最后一个联系人 或者是 已经找的联系人
        p = p->next;        //p往下移动
    }
    return p;               //返回联系人的位置
}
void delnode(ListNode *head)//删除联系人
{
    ListNode *p, *q;
    int flag;
    p = listfind(head);    //调用查找函数
    if(p == NULL){         //如果没有找的则结束删除
        printf("没有查到要删除的通讯者!\n");
        return;
    }
    printf("已找到,输入1删除,输入0结束操作\n");
    scanf("%d", &flag);
    if(flag){
        q = head;
        if(strcmp(head->name,p->name) == 0){    //如果要删除的联系人是头结点
            q = q->next;    //先让p变成第二个结点
            head = q;       //在让头结点后移 完成头结点的删除
        }
        else{               //如果不是头结点
        while(q != NULL && q->next != p)
            q = q->next;       //找到 要删除的联系人前一个节点
        q->next = p->next;     //删除结点
        printf("通讯者已被删除!\n");
        }
    }
}
void changenode(ListNode *head)
{
    ListNode *p, *q;
    int flag;
    p = listfind(head);    //调用查找函数
    if(p == NULL){         //如果没有找的则结束删除
        printf("没有查到要删除的通讯者!\n");
        return;
    }
    printf("已找到,输入1修改名字,输入2修改工作单位,输入3修改电话,输入4修改地址\n");
    while(1){
        scanf("%d", &flag);
        if(flag > 0 && flag < 4) break;
        printf("输入错误,请重新输入!\n");
    }
    printf("请输入");
    switch(flag){
        case 1:printf("新名字\n"); break;
        case 2:printf("新工作单位\n"); break;
        case 3:printf("新电话\n");break;
        case 4:printf("新地址\n");break;
    }
    char temp[30];
    getchar();
    gets(temp);
    switch(flag){
        case 1:strcpy(p->name,temp); break;
        case 2:strcpy(p->work,temp); break;
        case 3:strcpy(p->tel,temp); break;
        case 4:strcpy(p->addr,temp); break;
    }
    printf("修改成功!\n");
}
void printlist( struct ListNode *L )//输出联系人名单
{
     struct ListNode *p = L;
     while (p) {
           printf("%s\n%s\n%s\n%s\n\n", p->name, p->work, p->tel, p->addr);
           p = p->next;
     }
}
int menu_select(){      //选择菜单
    int A;
    printf("\n=============================================\n"
           "*             通讯录管理系统                *\n"
           "=============================================\n"
           "             1.通讯录的建立\n"
           "             2.通讯录的插入\n"
           "             3.通讯录的查询\n"
           "             4.通讯录的删除\n"
           "             5.通讯录的输出\n"
           "             6.通讯录的修改\n"
           "             0.退出管理系统\n"
           "=============================================\n\n"
           "请选择0-6:\n");
    while(1){      //输入的范围在0~5
        scanf("%d", &A);
        if(A < 0 || A > 6)
            printf("\n输入错误,重选0-6:\n");
        else
            break;
    }
    return A;
}

void save(ListNode *head)//存储联系人在文件中
{
    ListNode *p = head;
    if((fp = fopen(filename,"w")) == NULL){
        printf("无法打开此文件!\n");
        exit(0);
    }
    while(p){       //将每一个结点依次写入文件
        fprintf(fp,"%s\n%s\n%s\n%s\n\n", p->name, p->work, p->tel, p->addr);
        p = p->next;

    }
    fclose(fp);
}

void printtxl()     //文件中联系人的输出
{
    char ch;
    if((fp = fopen(filename,"r")) == NULL){
        printf("无法打开此文件!\n");
        exit(0);
    }
    ch = getc(fp);          ///逐一输出文件字符直到文件结束EOF
    while(ch != EOF){
        putchar(ch);
        ch = getc(fp);
    }
    fclose(fp);
}
int main()
{
    int t;
    ListNode *head, *p;
    while(1){
        switch(menu_select()){  //选择菜单中的选项之后 指向该选项的操作
            case 1:
            printf("\n+++++++++++++++++++++++++++++++++++++++++++++++\n"
                   "*              通讯录链表的建立               *\n"
                   "+++++++++++++++++++++++++++++++++++++++++++++++\n");
            head = createlist();
            break;
            case 2:
            printf("\n+++++++++++++++++++++++++++++++++++++++++++++++\n"
                   "*              通讯者信息的添加               *\n"
                   "+++++++++++++++++++++++++++++++++++++++++++++++\n"
                   "名字        工作单位    电话        地址\n");
            p = (ListNode *)malloc(sizeof(ListNode));
            scanf("%s%s%s%s", p->name, p->work, p->tel, p->addr);
            insertNode(head,p);
            break;
            case 3:
            printf("\n+++++++++++++++++++++++++++++++++++++++++++++++\n"
                   "*              通讯录信息的查询               *\n"
                   "+++++++++++++++++++++++++++++++++++++++++++++++\n");
            p = listfind(head);
            if(p != NULL){
                printf("-----------------------------------------------\n"
                       "名字        工作单位    电话        地址\n"
                       "-----------------------------------------------\n"
                       "%s\n%s\n%s\n%s%\n"
                       "-----------------------------------------------\n", p->name, p->work, p->tel,p->addr);
            }
            else
                printf("没查到要查询的通讯者!\n");
            break;
            case 4:
            printf("\n+++++++++++++++++++++++++++++++++++++++++++++++\n"
                   "*              通讯录信息的删除               *\n"
                   "+++++++++++++++++++++++++++++++++++++++++++++++\n");
            delnode(head);
            break;
            case 5:
            printf("\n+++++++++++++++++++++++++++++++++++++++++++++++\n"
                   "*                 通讯录的输出                *\n"
                   "+++++++++++++++++++++++++++++++++++++++++++++++\n");
            printlist(head);
            break;
            case 6:
            printf("\n+++++++++++++++++++++++++++++++++++++++++++++++\n"
                   "*                 通讯录的修改                *\n"
                   "+++++++++++++++++++++++++++++++++++++++++++++++\n");
            changenode(head);
            break;
            case 0:
            printf("\n                   退出系统!\n");
            t = 0;
            break;
        }
        if(t == 0)
            break;
    }
    printf("已经储存在文件中的联系人\n");
    save(head);
    printtxl();
    return 0;
}
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值