C语言用链表和文件实现简单通讯录管理系统(一改)

本文介绍了使用C语言实现的一个基础通讯录应用,包括添加、查看、按姓名和电话查询、排序以及删除联系人功能,通过文件操作存储和管理联系人信息。
摘要由CSDN通过智能技术生成

课后实践作业

实现简单的菜单设计,提供个人通讯录的管理,例如:

1添加联系人

2显示联系人

3按姓名查询

4按电话查询

5按姓名排序

6删除联系人

0退出

由于刚刚入门,好多想法实现不了,只能换其他简单、

笨的办法,中间好多不会的也是上网搜的ai、csdn....

总之,最后也是写出来了!!

以下是代码,大家有什么改进意见可以畅所欲言,欢迎斧正!!

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct contact
{
    char name[11];//姓名最多十个字母
    char gender;//性别,m(man)表示男,w(woman)表示女
    int id;//序号
    long long tele;//电话
    long long qq;
    int class;//班级
    struct contact *next;
} CON;
CON *head=NULL;//初始化全局变量head
void menu()//主菜单
{
    printf("选择你要进行的操作\n");
    printf("1.添加联系人\n2.显示联系人\n3.按姓名查询\n4.按电话查询\n5.按姓名排序\n6.删除联系人\n0.退出\n");
}
void add()//添加联系人并存入文件
{
    char name[11],gender;
    int id,class,n;
    long long tele,qq;
    FILE *fp;
    if((fp=fopen("contacts.txt","a"))==NULL)//注意这里采用的时追加信息,即在原联系人后继续添加
    {
        printf("open file error!\n");
        exit(1);
    }
    printf("请输入要添加的联系人个数:\n");
    scanf("%d",&n);
    printf("请输入要添加的联系人信息:\n");//每人各占一行,每个信息用空格隔开
    for(int i=0; i<n; i++)
    {
        scanf("%s %d %c %lld %lld %d",name,&id,&gender,&tele,&qq,&class);
        fprintf(fp,"%s %d %c %lld %lld %d\n",name,id,gender,tele,qq,class);
    }
    fclose(fp);
}
void save()//将更改后的信息链表存入文件
{
    CON *s;
    s=head->next;
    FILE *fp;
    if((fp=fopen("contacts.txt","w"))==NULL)
    {
        printf("open file error!\n");
        exit(1);
    }
    while(s!=NULL)//遍历整个链表,依次存入文件
    {
        fprintf(fp,"%s %d %c %lld %lld %d\n",s->name,s->id,s->gender,s->tele,s->qq,s->class);
        s=s->next;
    }
    fclose(fp);

}
void view()//显示联系人信息
{
    char name[11],gender;
    int id,class;
    long long tele,qq;
    FILE *fp;
    if((fp=fopen("contacts.txt","r"))==NULL)
    {
        printf("open file error!\n");
        exit(1);
    }
    printf("---------------------------------通讯录---------------------------------\n");
    printf("|姓名\t\t|序号\t|性别\t|电话\t\t|qq\t\t|班级\t|\n");
    while((fscanf(fp,"%s %d %c %lld %lld %d\n",&name,&id,&gender,&tele,&qq,&class))!=EOF)//判断文件中信息是否存在,存在则打印
        printf("|%-15s|%d\t|%c\t|%-15lld|%-15lld|%d\t|\n",name,id,gender,tele,qq,class);
    printf("------------------------------------------------------------------------\n");
    fclose(fp);
}
CON *chain()//将文件中的联系人信息存在新链表中
{
    CON *h,*p,*q;
    char name[11],gender;
    int id,class;
    long long tele,qq;
    FILE *fp;
    h=(CON*)malloc(sizeof(CON));//表头
    p=h;
    if((fp=fopen("contacts.txt","r"))==NULL)
    {
        printf("open file error!\n");
        exit(1);
    }
    while((fscanf(fp,"%s %d %c %lld %lld %d\n",&name,&id,&gender,&tele,&qq,&class))!=EOF)//提取文件中的信息
    {
        q=(CON*)malloc(sizeof(CON));
        strcpy(q->name,name);
        q->id=id;
        q->gender=gender;
        q->tele=tele;
        q->qq=qq;
        q->class=class;
        p->next=q;
        p=q;
    }//构建链表并存入信息
    p->next=NULL;
    return h;
}
void search_name()//按姓名查找
{
    head=chain();
    CON *p=head->next;
    char name[11];
    printf("请输入您要查找的姓名:\n");
    scanf("%s",name);
    while(p!=NULL)// 遍历整个链表
    {
        if(strcmp(name,p->name)==0)//找到目标信息
        {
            printf("|姓名\t\t|序号\t|性别\t|电话\t\t|qq\t\t|班级\t|\n");
            printf("|%-15s|%d\t|%c\t|%-15lld|%-15lld|%d\t|\n",p->name,p->id,p->gender,p->tele,p->qq,p->class);
            return ;
        }
        else
            p=p->next;
    }
    printf("该姓名不存在!\n");
}
void search_tele()//按电话号码查询
{
    head=chain();
    CON *p;
    long long tele;
    printf("请输入您要查找的电话:\n");
    scanf("%lld",&tele);
    p=head->next;
    while(p!=NULL)// 遍历整个链表
    {
        if(p->tele==tele)//找到目标信息
        {
            printf("|姓名\t\t|序号\t|性别\t|电话\t\t|qq\t\t|班级\t|\n");
            printf("|%-15s|%d\t|%c\t|%-15lld|%-15lld|%d\t|\n",p->name,p->id,p->gender,p->tele,p->qq,p->class);
            return ;
        }
        else
            p=p->next;
    }
    printf("该电话不存在!\n");
}
void sort_contact()//按姓名排序信息
{
    int swapped;//用于判断是否发生交换
    CON* current;//用于遍历链表
    CON* last = NULL;//记录最后一个已排序的节点
    if (head == NULL)
        return;
    do
    {
        swapped = 0;
        current = head;
        while (current->next != last)//遍历所有已排序之外的节点
        {
            if (strcmp(current->name, current->next->name) > 0)//发生交换的条件
            {
                // 交换节点
                char name[11],gender;
                int id,class;
                long long tele,qq;

                strcpy(name,current->name);
                gender = current->gender;
                id=current->id;
                tele=current->tele;
                qq=current->qq;
                class=current->class;

                strcpy(current->name, current->next->name);
                current->gender = current->next->gender;
                current->id = current->next->id;
                current->tele = current->next->tele;
                current->qq = current->next->qq;
                current->class = current->next->class;

                strcpy(current->next->name, name);
                current->next->gender = gender;
                current->next->id = id;
                current->next->tele = tele;
                current->next->qq = qq;
                current->next->class = class;

                swapped = 1;
            }
            current = current->next;
        }
        last = current;//
    }while (swapped);  //发生交换继续循环
}
void updateid()//把序号也按姓名顺序排出
{

    CON *p;
    p=head->next;
    int i=1;//i用于更新id的值
    while(p!=NULL)
    {
        p->id=i++;
        p=p->next;
    }
}
CON delete_contact()//删除联系人信息
{
    CON *p1,*p2;
    int op;//确定是否删除
    head=chain();//提取文件信息创建链表
    char name[11];
    printf("请输入您要删除的联系人的姓名:\n");
    scanf("%s",name);
    p1=head->next;     //跳过第一个空的结点
    if(p1==NULL)
    {
        printf("List is NULL!\n");
        return ;
    }
    while(strcmp(name,p1->name)!=0&&p1->next!=NULL)     //p1指向的不是要找的点,并且后面还有结点
    {
        p2=p1;
        p1=p1->next;//则p1后移一个结点
    }
    if(strcmp(name,p1->name)==0)      //找到要删除的结点
    {
        printf("|姓名\t\t|序号\t|性别\t|电话\t\t|qq\t\t|班级\t|\n");
        printf("|%-15s|%d\t|%c\t|%-15lld|%-15lld|%d\t|\n",p1->name,p1->id,p1->gender,p1->tele,p1->qq,p1->class);
        printf("是否要删除该联系人?\n1.是 2.否\n");
         scanf("%d",&op);
        if(p1==head->next&&op==1)
        {
           head->next=p1->next; //若p1指向第一个有效结点,则把第2个有效结点地址赋给h->next
           printf("删除成功!返回主菜单\n");
        }
        else if(p1!=head->next&&op==1)
        {
           p2->next=p1->next;//跳过p1,p2之后直接是p1指向的下一个节点
           printf("删除成功!返回主菜单\n");
        }
        else
            {
                printf("取消成功!返回主菜单\n");
                return;}
        free(p1);//释放内存
        save();
    }
    else printf("未找到该联系人!\n");    //找不到指定结点的输出提示
}
int main()
{
    int op;
    while(1)
    {
        menu();
        scanf("%d",&op);
        switch(op)//通过op选择要进行的操作
        {
        case 1:
            add();break;
        case 2:
            view();break;
        case 3:
            search_name();break;
        case 4:
            search_tele();break;
        case 5:
        {
            head=chain();//创建链表存入信息
            sort_contact();//按姓名排序节点
            updateid();//更新序号
            save();//保存
            view();//输出链表
        }
        break;
        case 6:
            delete_contact();break;
        case 0:return 0;
        }
    }
    return 0;
}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值