通讯录——C语言实现

1.1 需求概述

   此软件为通讯录管理系统软件,用于管理用户通信联系人的名片信息。其中,名片信息包括,编号、姓名、性别、生日、联系电话、QQ、联系地址及备注等;通过名片信息可以清楚、直观地体现名片信息。

1.2 功能需求

   此软件具有信息浏览,增删、查询、存读档等功能。其中可以通过姓名增删联系人,通过姓名、编号或者联系电话查询联系人,可以将联系人信息存档及通过文本文件读取联系人的信息。

1.3 功能结构图

在这里插入图片描述

1.4 软件设计

   软件的实现牵涉到数据结构的设计问题,本程序选择链表作为各种操作的基础,当然,选择数组亦可,二者在操作上各有优缺点,在删除操作时前者更加方便,查找联系人时后者更方便。完整C代码如下:

/************************************************************************************
/////////////////////////////////////////////////////////////////////////////////////
说明:本文档为C语言版本的通讯录的基本功能实现的源程序,主要的操作为:结构体
链表的基本使用、读和写文件等。

作者:24K纯学渣
日期:2020/2/3

关注微信公众号“24K纯学渣”,
有更多详细的相关文档资料,另可于此可获取作者联系方式,帮助解决调试问题。

-------------------------------------------------------------------------------------
学海无涯,让我们一起学习,共同进步!

//////////////////////////////////////////////////////////////////////////////////////
*************************************************************************************/
/*头文件包含*/
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<time.h>
#include<windows.h>

/*定义新的结构体数据类型*/
typedef struct _Person
{
  int code;             //编号
  char name[10];        //姓名
  char sex[10];         //性别
  char birthday[25];    //生日
  char telphone[15];    //联系方式
  char qqtouch[20];     //QQ号
  char address[50];     //地址
  char remark[50];      //备注
  struct _Person *next; //指向下一个节点
}Person;

/*************************************************************
函数功能:打印单个链表节点的信息
形参解释:Person *nod 头指针
函数返回值:无
*************************************************************/
void printOne(Person *nod)
{
    printf("Code:%d\n",nod->code);
    printf("Name:%s\n",nod->name);
    printf("Gender:%s\n",nod->sex);
    printf("Birthday:%s\n",nod->birthday);
    printf("Tel:%s\n",nod->telphone);
    printf("QQ:%s\n",nod->qqtouch);
    printf("Address:%s\n",nod->address);
    printf("Note:%s\n",nod->remark);
    return;
}

/*************************************************************
函数功能:添加联系人
形参解释:Person *per 头指针
函数返回值:返回头指针
*************************************************************/
Person *Add_contacts(Person *per)
{
    Person *node, *rear;
    node = (Person *)malloc(sizeof(Person));  //分配内存
    printf("Code:");
    scanf("%d",&(node->code));  //输入信息

    printf("Name(Must be entered):");
    scanf("%s",(node->name));

    printf("Birthday(For example 2000-01-01):");
    scanf("%s",node->birthday);

    printf("(Female or Male):");
    scanf("%s",node->sex);

    printf("Telephone(Must be Enter):");
    scanf("%s",node->telphone);

    printf("QQ:");
    scanf("%s",node->qqtouch);

    printf("Address:");
    scanf("%s",node->address);

    printf("Remark:");
    scanf("%s",node->remark);

    node->next = NULL;
    if(per == NULL) //如果头指针为空,新添加的节点为头节点
    {
        per = node;
        return per;
    }
    else //否则添在后面
    {
        rear = per;
        while((rear ->next)!=NULL)
        {
            rear = rear->next;
        }
        rear->next = node;
        return per;
    }
}

/*************************************************************
函数功能:在控制台输出联系人文档中的所有信息
形参解释:Person *h头指针
函数返回值:无
*************************************************************/
void Output_allf(Person *h)  //从文档中输出所有联系人的所有信息
{
    if(h==NULL)
        printf("Error\n");
    Person *nod;
    nod = h;
    while(nod!=NULL)
    {
        printOne(nod);  //打印单个节点的信息
        nod = nod->next;
    }
    return;
}

/*************************************************************
函数功能:查找联系人
形参解释:Person *per 头指针
函数返回值:返回查找到的节点指针
*************************************************************/
Person *Find_some(Person *per)
{
    char s[20],co[10];
    Person *node;
    printf("Input the name(/code/Tel)to continue:\n");//支持按姓名、编号或电话查找
    scanf("%s",s);
    node = per;
    if(node == NULL) //如果头指针为空,报错!
    {
        printf("Error!\n");
        return NULL;
    }
    while(node != NULL)
    {
        itoa(node->code,co,10); //将int型的编号转化为字符串型的数据,便于比较
        if(strcmp((node->name),s)==0) //比较节点信息
        {
            break;
        }
        else if(strcmp((node->telphone),s)==0)
        {
            break;
        }
        else if(strcmp(co,s)==0)
        {
            break;
        }
        node = node->next;
    }
    if(node != NULL)
    {
        printOne(node); //打印出查找到的节点信息
    }
    else{
        printf("No such a guy!\n");
    }
    return node;
}

/*************************************************************
函数功能:删除联系人
形参解释:Person *per 头指针
函数返回值:头指针
*************************************************************/
Person *Delete_contact(Person *per) //删除单个联系人信息
{
    char s[20];
    Person *p,*q;
    Output_allf(per); //打印出所有信息
    printf("Please enter the name you want to delete:\n");
    scanf("%s",s);
    if(per == NULL)
    {
        printf("Error,can't find the target!\n");
        return per;
    }
    p = per;
    q = p->next;
    if(strcmp((p->name),s)==0) //若待删除的节点首节点
    {
        free(p); //释放内存
        printf("delete done\n");
        return q;
    }
    else
    {
        while(q!=NULL)
        {
            if(strcmp((q->name),s)==0)
            {
                if(q->next==NULL) //若待删除的节点为尾节点
                {
                    free(q);
                    p->next = NULL;
                    printf("Delete done!\n");
                    break;
                }
                else  //若待删除的节点处于链表的中间位置
                {
                    p->next = q->next;
                    free(q);
                    printf("Delete done!\n");
                    break;
                }
            }
            p = q;
            q = q->next;
        }
        return per;
    }
}

/*************************************************************
函数功能:修改某一联系人的信息
形参解释:Person *per 头指针
函数返回值:无
*************************************************************/
void Modify_contact(Person *per)
{
    Person *node;
    node = Find_some(per); //先查找到该节点
    printf("Code:");  //从头输入节点信息
    scanf("%d",&(node->code));

    printf("Name(Must be entered):");
    scanf("%s",(node->name));

    printf("Birthday(For example 2000-01-01):");
    scanf("%s",node->birthday);

    printf("(Female or Male):");
    scanf("%s",node->sex);

    printf("Telephone(Must be Enter):");
    scanf("%s",node->telphone);

    printf("QQ:");
    scanf("%s",node->qqtouch);

    printf("Address:");
    scanf("%s",node->address);

    printf("Remark:");
    scanf("%s",node->remark);
    return;
}

/*************************************************************
函数功能:以.txt格式保存结构体数组中的信息
形参解释:Person *per 头指针
函数返回值:无
*************************************************************/
void Save_txt(Person *per)
{
    Person *nd;
    FILE *fp;
    if((fp=fopen("e:\\my_friends.txt","w"))==NULL) //若不存在该文件,将会重新创建
    {
        printf("Cannot open the file!\n");
        return;
    }
    if(per == NULL) //首节点必须存在
    {
        printf("Error!\n");
        return;
    }
    nd = per;
    while(nd != NULL) //依次打印信息
    {
        fprintf(fp,"Code:");
        fprintf(fp,"%d",nd->code);
        fprintf(fp,"\n");

        fprintf(fp,"Name:");
        fprintf(fp,"%s",nd->name);
        fprintf(fp,"\n");

        fprintf(fp,"Gender:");
        fprintf(fp,"%s",nd->sex);
        fprintf(fp,"\n");

        fprintf(fp,"Birthday date:");
        fprintf(fp,"%s",nd->birthday);
        fprintf(fp,"\n");

        fprintf(fp,"Tel:");
        fprintf(fp,"%s",nd->telphone);
        fprintf(fp,"\n");

        fprintf(fp,"QQ:");
        fprintf(fp,"%s",nd->qqtouch);
        fprintf(fp,"\n");

        fprintf(fp,"Address:");
        fprintf(fp,"%s",nd->address);
        fprintf(fp,"\n");

        fprintf(fp,"Remark:");
        fprintf(fp,"%s",nd->remark);
        fprintf(fp,"\n");
        fprintf(fp,"---------------------------------------------------\n");
        nd = nd->next;
    }
    fclose(fp);
    printf("Save done\n");
    return;
}


/*************************************************************
函数功能:主函数
形参解释:无
函数返回值:无意义
*************************************************************/
int main()
{
    Person *head = NULL;
    int mode; //工作模式
    printf("\tWelcome!\n");
    while(1)  //循环菜单
    {
        printf("0 ----- Output all contacts information\n");
        printf("1 ----- Find contacts\n");
        printf("2 ----- Add contacts\n");
        printf("3 ----- Delete contacts\n");
        printf("4 ----- modify contacts\n");
        printf("5 ----- Exit the program\n");
        printf("6 ----- Save by .txt\n");
        printf("Please choose the mode:\n");
        scanf("%d",&mode);
        switch(mode)
        {
            case 2: head = Add_contacts(head);break;
            case 0: Output_allf(head);break;
            case 3: head = Delete_contact(head); break;
            case 1: Find_some(head); break;
            case 4: Modify_contact(head); break;
            case 6: Save_txt(head); break;
            case 5: printf("\n Thanks for your using! Good bye!\n"); break;
        }
        if(mode==5)
            break;
        printf("Press any key to continue!\n");
        fflush(stdin);   //清空缓存区的保存的信息
        getchar();
        system("cls");  //这一句可以清空控制台信息
    }
    return 0;
}





   另外,限于文章篇幅,数组版本的实现方式不再粘贴出,如有需要,请搜素微信公众号“24K纯学渣”,回复关键词“通讯录”,可获取完整的数组实现(两种方法实现)、链表实现的C源码等。

发布了25 篇原创文章 · 获赞 9 · 访问量 6194

猜你喜欢

转载自blog.csdn.net/qq_42144047/article/details/103927945