C语言实现简单的通信录

实验要求

  • 使用链表作为数据结构
  • 实现文件保存数据
  • 实现基础的增删改查功能

实验分析

0.定义链表以及文件的路径

#include 
#include 
#include 
#define F_PATH "E:\\phone.txt" //定义文件路径
typedef struct Node{           //定义数据结构
    char name[20];
    char  Iphonedata[11];
    struct Node *next;
}Node,*LinkList;
LinkList L;                    //定义全局变量链表

1.我们需要四个函数来实现增删改查,四个函数分别为:

添加用户(AddUser()),删除用户(DeleteUser),修改号码(UpdateUser),查找用户(SearchUser),我们来看一下主函数的代码:
int main(){
    int sel;
    L=(LinkList)malloc(sizeof(Node));//初始化链表
    L->next=NULL;                    //读取文件数据
    ReadFile();
    while(1){
        printf("\t通讯录\n");
        printf("1.显示用户信息\n");
        printf("2.增加用户信息\n");
        printf("3.删除用户信息\n");
        printf("4.查找用户信息\n");
        printf("5.修改用户信息\n");
        printf("0.退出系统\n");
        printf("请选择(0--5)的命令:\n");
        scanf("%d",&sel);
        switch(sel){
        case 1: PrintUserInfo();break;//打印用户信息
        case 2: AddUser();break;      //添加用户
        case 3: DeleteUser();break;   //删除用户
        case 4: SearchUser();break;   //查找用户
        case 5: UpdateUser();break;   //更新用户
        case 0: return 0;break;       //退出系统
        }
    }
    system("pause");
    return 0;
}

注意这里的ReadFile()函数,是将文件里面的内容添加到链表中,对应的代码如下:

/*
* 在界面打开前首先从文件读取数据
* 文件路径我们设置为 E:\\phone.txt
*/
int ReadFile(){
    char name[15],number[20];
    FILE *fp=fopen(F_PATH,"r");/*以读模式("r")打开文件F_PATH*/
    while(fscanf(fp,"%s",name)!=EOF&&fscanf(fp,"%s",number)!=EOF){/*从文件读取名称和号码字符串*/
        AddListFromFile(name,number);//抽取出添加到文件的函数
    }
    fclose(fp); /*关闭文件*/
    return 0;
}

抽取出添加到文件的函数的代码为:

void AddListFromFile(char *name,char *number){  
    LinkList p,r;
    r=L;
    while(r->next!=NULL){
        r=r->next;
    }
    p=(LinkList)malloc(sizeof(Node));
    if(p!=NULL){//插入数据到链表
        strcpy(p->name,name);
        strcpy(p->Iphonedata,number);
        p->next=NULL;
        r->next=p;  
    }   
}

接下来我们按照函数的顺序来一次实现上面的四个函数:

2.显示用户信息

int PrintUserInfo(){
    LinkList p;
    if(L->next==NULL){           //如果链表为空,则显示通信录为空
        printf("通信录为空!\n");
        return ;
    }
    p=L->next;
    while(p!=NULL){              //一次遍历链表
        printf("姓名:%s\t手机号:%s\t\n",p->name,p->Iphonedata);
        p=p->next;
    }
}

3.添加用户信息

void AddUser(){
    LinkList p,r;
    FILE *fp=fopen(F_PATH,"a+");//以添加append模式("a+")打开文件F_PATH
    int number,j;
    r=L;
    while(r->next!=NULL){
        r=r->next;
    }
    printf("进行通信录的输入,1 or 0?\n");
    scanf("%d",&j);
    getchar();
    while(j){
        p=(LinkList)malloc(sizeof(Node));
        if(p!=NULL){
            printf("请输入姓名:\n");
            gets(p->name);
            fprintf(fp,"%s ",p->name);         //写入姓名到文件
            printf("请输入电话号码:\n");
            gets(p->Iphonedata);
            fprintf(fp,"%s\n",p->Iphonedata);  //写入电话号码到文件
            p->next=NULL;
            r->next=p;  
            printf("进行通信录的输入,1 or 0?\n");
            scanf("%d",&j);
            getchar();
        }   
    }
    fclose(fp); //关闭文件 一定要关闭哦!
}

4.删除用户信息

void DeleteUser(){
    LinkList r,p;
    char name[20];
    r=L;
    getchar();
    printf("请输入将要删除的姓名:");//根据姓名删除
    gets(name);
    while(r->next!=NULL){
        if(strcmp(name,r->next->name)==0)
            break;
        else
            r=r->next;
    }
    if(r->next!=NULL){
        p=r->next;
        r->next=p->next;
        free(p);
    }
    WriteToFile();         //删除链表数据之后更新文件
    printf("删除成功!\n");
}

如果我们只是删除了链表里面的数据,对应的文件里面数据没有更新是不行的,这时候我们需要使用WriteToFile()方法将链表里面的数据重新写入文件,这个函数对应的代码为:

void WriteToFile(){
    LinkList p;
    FILE *fp=fopen(F_PATH,"w");//以w写入文件会清空文件原有的信息
    p=L->next;
    while(p!=NULL){
        fprintf(fp,"%s %s\n",p->name,p->Iphonedata);
        p=p->next;
    }
    fclose(fp); /*关闭文件*/
}

5.查找用户信息

void SearchUser(){ 
    LinkList r;
    char name[20]; 
    r=L;
    getchar();
    printf("请输入将要查找的姓名:");//根据姓名来查找
    gets(name);
    while(r!=NULL){
        if(strcmp(name,r->name)==0) break;
        else r=r->next;
    }
    if(r!=NULL){
        printf("姓名:%s\t\t手机号:%s\t\n",r->name,r->Iphonedata);
    }else printf("不存在这个人!\n");
}

6.更新用户信息

void UpdateUser(){ 
    LinkList r;
    char name[20]; 
    char phoneNumber[20];
    r=L;
    getchar();
    printf("请输入将要修改号码的用户姓名:"); //根据用户姓名来更新数据
    gets(name);
    while(r!=NULL){
        if(strcmp(name,r->name)==0) break;
        else r=r->next;
    }
    if(r!=NULL){
        printf("请输入将要修改后的号码:");

        gets(phoneNumber);
        strcpy(r->Iphonedata,phoneNumber);
        WriteToFile();                       //更新完成之后要将链表的数据重新写回文件
        printf("修改成功!\n");
    }else printf("不存在这个人!\n");
}

同样,更新完链表的数据之后要将链表的数据重新写回文件。

7.完整的程序

#include 
#include 
#include 
#define F_PATH "E:\\phone.txt" //定义文件路径
typedef struct Node{           //定义数据结构
    char name[20];
    char  Iphonedata[11];
    struct Node *next;
}Node,*LinkList;
LinkList L;                    //定义全局变量链表

void WriteToFile(){
    LinkList p;
    FILE *fp=fopen(F_PATH,"w");//以w写入文件会清空文件原有的信息
    p=L->next;
    while(p!=NULL){
        fprintf(fp,"%s %s\n",p->name,p->Iphonedata);
        p=p->next;
    }
    fclose(fp); /*关闭文件*/
}
void PrintUserInfo(){
    LinkList p;
    if(L->next==NULL){           //如果链表为空,则显示通信录为空
        printf("通信录为空!\n");
        return;
    }
    p=L->next;
    while(p!=NULL){              //一次遍历链表
        printf("姓名:%s\t手机号:%s\t\n",p->name,p->Iphonedata);
        p=p->next;
    }
}

void AddUser(){
    LinkList p,r;
    FILE *fp=fopen(F_PATH,"a+");//以添加append模式("a+")打开文件F_PATH
    int number,j;
    r=L;
    while(r->next!=NULL){
        r=r->next;
    }
    printf("进行通信录的输入,1 or 0?\n");
    scanf("%d",&j);
    getchar();
    while(j){
        p=(LinkList)malloc(sizeof(Node));
        if(p!=NULL){
            printf("请输入姓名:\n");
            gets(p->name);
            fprintf(fp,"%s ",p->name);         //写入姓名到文件
            printf("请输入电话号码:\n");
            gets(p->Iphonedata);
            fprintf(fp,"%s\n",p->Iphonedata);  //写入电话号码到文件
            p->next=NULL;
            r->next=p;  
            printf("进行通信录的输入,1 or 0?\n");
            scanf("%d",&j);
            getchar();
        }   
    }
    fclose(fp); //关闭文件 一定要关闭哦!
}
void AddListFromFile(char *name,char *number){  
    LinkList p,r;
    r=L;
    while(r->next!=NULL){
        r=r->next;
    }
    p=(LinkList)malloc(sizeof(Node));
    if(p!=NULL){//插入数据到链表
        strcpy(p->name,name);
        strcpy(p->Iphonedata,number);
        p->next=NULL;
        r->next=p;  
    }   
}

int UpdateUser(){ 
    LinkList r;
    char name[20]; 
    char phoneNumber[20];
    r=L;
    getchar();
    printf("请输入将要修改号码的用户姓名:"); //根据用户姓名来更新数据
    gets(name);
    while(r!=NULL){
        if(strcmp(name,r->name)==0) break;
        else r=r->next;
    }
    if(r!=NULL){
        printf("请输入将要修改后的号码:");

        gets(phoneNumber);
        strcpy(r->Iphonedata,phoneNumber);
        WriteToFile();                       //更新完成之后要将链表的数据重新写回文件
        printf("修改成功!\n");
    }else printf("不存在这个人!\n");
    return 0;
}

int SearchUser(){ 
    LinkList r;
    char name[20]; 
    r=L;
    getchar();
    printf("请输入将要查找的姓名:");//根据姓名来查找
    gets(name);
    while(r!=NULL){
        if(strcmp(name,r->name)==0) break;
        else r=r->next;
    }
    if(r!=NULL){
        printf("姓名:%s\t\t手机号:%s\t\n",r->name,r->Iphonedata);
    }else printf("不存在这个人!\n");
    return 0;
}
void DeleteUser(){
    LinkList r,p;
    char name[20];
    r=L;
    getchar();
    printf("请输入将要删除的姓名:");//根据姓名删除
    gets(name);
    while(r->next!=NULL){
        if(strcmp(name,r->next->name)==0)
            break;
        else
            r=r->next;
    }
    if(r->next!=NULL){
        p=r->next;
        r->next=p->next;
        free(p);
    }
    WriteToFile();         //删除链表数据之后更新文件
    printf("删除成功!\n");
}
/*
* 在界面打开前首先从文件读取数据
* 文件路径我们设置为 E:\\phone.txt
*/
int ReadFile(){
    char name[15],number[20];
    FILE *fp=fopen(F_PATH,"r");/*以读模式("r")打开文件F_PATH*/
    while(fscanf(fp,"%s",name)!=EOF&&fscanf(fp,"%s",number)!=EOF){/*从文件读取名称和号码字符串*/
        AddListFromFile(name,number);
    }
    fclose(fp); /*关闭文件*/
    return 0;
}
int main(){
    int sel;
    L=(LinkList)malloc(sizeof(Node));
    L->next=NULL;
    ReadFile();
    while(1){
        printf("\t通讯录\n");
        printf("1.显示用户信息\n");
        printf("2.增加用户信息\n");
        printf("3.删除用户信息\n");
        printf("4.查找用户信息\n");
        printf("5.修改用户信息\n");
        printf("0.退出系统\n");
        printf("请选择(0--5)的命令:\n");
        scanf("%d",&sel);
        switch(sel){
        case 1: PrintUserInfo();break;//打印用户信息
        case 2: AddUser();break;      //添加用户
        case 3: DeleteUser();break;   //删除用户
        case 4: SearchUser();break;   //查找用户
        case 5: UpdateUser();break;   //更新用户
        case 0: return 0;break;       //退出系统
        }
    }
    system("pause");
    return 0;
}

实验总结

这次实验使我们知道了文件的读写知识以及有关单向链表的基本知识。

你可能感兴趣的:([,C,C语言基础,])