用链表实现通讯录,并保存到文件

用链表实现通讯录,并保存到文件。
包含的功能有:1、添加好友;2、查看列表;3、删除好友;4、查找好友;5、修改信息;6、保存退出。
在进入时读取文件中的联系人信息,再退出时重新保存。


头文件:

#ifndef _STRUCT_H_
#define _STRUCT_H_

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

int i;                                              //定义全局变量i

struct node
{
    int ID;
    char name[20];
    char ismale[20];
    char tel[20];
    char qq[20];
    char address[20];
    char remark[20];                                //保存联系人信息
    struct node *next;                              //结构体类型的指针,保存下一个结构体的地址
};

void clear();
void interface();
void read_data(struct node *header);
int insert_tail( struct node *header );
void printfcon( struct node *header, int j );
void list( struct node *header );
int findnum( struct node *header, char *s, int *accumlate );
void seek( struct node *header );
int coverdata( struct node *header, int j );
void mydelete( struct node *header );
void setid( struct node *header );
int modify( struct node *header, int j );
void revise( struct node *header );
void write_data(struct node *header);

#endif

有关文件操作的函数:

#include "struct.h"

void read_data(struct node *header)
{
    FILE *fp = fopen("Maillist", "ab+");
    if (fp == NULL)
    {
        perror ("fopen");
        return;
    }

    struct node *temp = header;

    // 读记录的个数
    fread (&i, sizeof(int), 1, fp);

    int j;
    for (j = 0; j < i; j++)
    {
        int len;
        fread (&len, sizeof(int), 1, fp);

        struct node *p = (struct node *)malloc(sizeof(struct node));
        if( p == NULL )
        {
            printf("malloc error!\n");
            return ;
        }

        // 读取数据
        int ret = fread (p, len, 1, fp);
        printf("%d\n",ret);

        while( temp->next != NULL )
        {
            temp = temp->next;
        }
        temp->next = p;                                                 //找到最后一个结点,将结点p尾插进链表
        p->next = NULL;
    }

    fclose(fp);
}

void write_data(struct node *header)
{
    FILE *fp = fopen("Maillist", "wb+");
    if (fp == NULL)
    {
        perror ("fopen");
        return;
    }
    // 要写入个数
    fwrite(&i, sizeof(int), 1, fp);

    struct node *p = header;
    while( p->next != NULL )
    {
        p = p->next;

        // 写入数据长度
        int len = sizeof(struct node);
        fwrite(&len, sizeof(int), 1, fp);

        // 写入数据
        fwrite(p, len, 1, fp);
    }
    fclose(fp);
}

插入联系人信息:

#include "struct.h"

int insert_tail( struct node *header )                                  //定义添加联系人函数
{
    char c = 0;
    struct node *temp = header;

    do
    {
        clear();
        struct node *p = (struct node *)malloc(sizeof(struct node));
        if( p == NULL )
        {
            printf("malloc error!\n");
            return -1;
        }

        printf("请输入联系人姓名:");                                    //录入联系人信息
        scanf("%s",p->name);

        printf("请输入联系人性别:");
        scanf("%s",p->ismale);

        printf("请输入联系人电话号码:");
        scanf("%s",p->tel);

        printf("请输入联系人QQ号:");
        scanf("%s",p->qq);

        printf("请输入联系人家庭地址:");
        scanf("%s",p->address);

        printf("备注:");
        scanf("%s",p->remark);

        p->ID = i;  
        i++;                                                            //录完后让i++

        while( temp->next != NULL )
        {
            temp = temp->next;
        }
        temp->next = p;                                                 //找到最后一个结点,将结点p尾插进链表
        p->next = NULL;

        printf("是否继续添加? (y/n) :");
        __fpurge(stdin);                                                //清除缓冲区
        c = getchar();

    }while( c == 'y' );                                                 //do while语句,当c不等于y时退出循环,即不再继续添加
}

查看联系人列表:

#include "struct.h"

void list( struct node *header )                                //定义联系人列表函数,输出所有联系人信息
{
    clear();

    int j = 0;

    for( j = 0; j <= i; j++ )
    {
        printfcon( header, j );                                 // 调用printfcon函数,输出每个联系人的信息
    }
}

void printfcon(struct node *header, int j)                      //定义打印单个联系人信息函数
{
    struct node *p = header;
    while( p->next != NULL )
    {
        p = p->next;
        if( p->ID == j )
        {
            printf("编号:%d\n",p->ID);                            //遍历链表,输出ID为j的联系人信息
            printf("姓名:%s\n",p->name);
            printf("性别:%s\n",p->ismale);
            printf("电话:%s\n",p->tel);
            printf("QQ号:%s\n",p->qq);
            printf("地址:%s\n",p->address);
            printf("备注:%s\n",p->remark);
            printf("\n");
        }
    }
}

删除联系人:

#include "struct.h"

void mydelete( struct node *header )                            //定义删除联系人函数
{
    char c = 0;
    struct node *p = header;
    do
    {
        clear();

        int j = 0;
        int temp = 0;
        int accum = 0;
        int a[20] = {0};
        char name[20] = {0};

        printf("请输入你想删除的联系人的姓名:");
        scanf("%s",name);

        accum = findnum( p, name, a );                          //调用findnum函数,并把找到几个联系人赋给accum

        if( accum == 0 )
        {
            printf("此联系人不存在!\n");
        }

        else if( accum == 1 )
        {
            temp = a[0];
            printfcon( p, temp );
            coverdata( p, temp );
        }

        else if( accum > 1 )
        {
            printf("有%d个联系人!\n",accum);                 //如果找到不止一个联系人,一个个输出这些联系人信息,让操作者选择是否要删除
            for( j = 0; j < accum; j++ )
            {
                temp = a[j];
                printfcon( p, temp );
                coverdata( p, temp );
            }
        }
        setid( p );

        printf("是否继续删除? (y/n): \n");
        __fpurge(stdin);
        c = getchar();

    }while( c == 'y' );                                         //do while语句,用来控制是否继续删除,只有输入y时才继续删除
}

int coverdata( struct node *header, int j )                     //定义覆盖信息函数
{
    printf("是否删除该联系人?(y/n)\n");                 
    __fpurge(stdin);

    if( getchar() == 'y' )                                      //当输入的字符为y时执行操作
    {
        struct node *prev = NULL;
        struct node *p = header;

        while( p->next != NULL )
        {
            prev = p;
            p = p->next;
            if( p->ID == j )
            {
                prev->next = p->next;
                printf("删除成功!\n");
                printf("\n");
                free(p);
                p = NULL;
                i--;
                return 0;                                       //当ID等于j时,让p前一个结点指向p后一个结点,释放p,让i-1
            }
        }
        printf("delete error!\n");
    }
}

void setid( struct node *header )
{
    struct node *p = header;
    int j = 0;

    while( p->next !=NULL )
    {
        p = p->next;                                    //跳过头结点或指向下一个结点
        p->ID = j++;                                    //重置每个结点的ID
    }
}

查找联系人:

#include "struct.h"

void seek( struct node *header )                                //定义查找函数,通过姓名查找
{
    char c = 0;
    struct node *p = header;
    do
    {
        clear();

        int j = 0;
        int temp = 0;
        int accum = 0;
        int a[20] = {0};
        char name[20] = {0};

        printf("请输入你想查找的联系人的姓名:");
        scanf("%s",name);

        accum = findnum( p, name, a );                          //调用findnum函数,并把找到几个联系人赋给accum

        if( accum == 0 )
        {
            printf("此联系人不存在!\n");
        }

        else if( accum == 1 )                                   //如果找到一个联系人,输出这个联系人的信息
        {
            temp = a[0];
            printfcon( p, temp );
        }

        else if( accum > 1 )                                    //找到不止一个联系人,输出全部联系人信息
        {
            printf("有%d个联系人!\n",accum);
            for( j = 0; j < accum; j++ )
            {
                temp = a[j];
                printfcon( p, temp );
            }
        }
            printf("是否继续查找? (y/n) :");
            __fpurge(stdin);
            c = getchar();

    }while( c == 'y' );                                         //do while语句用来控制是否继续查找,当输入为y时继续查找
}

int findnum( struct node *header, char *s, int *accumlate )     //定义找到联系人编号函数,找到编号存入数组accumlate
{
    int m = 0;
    int j = 0;
    struct node *p = header;

    for( m = 0; m <= i; m++ )
    {
        if( strcmp( s, p->name ) == 0 )
        {
            accumlate[j++] = p->ID;                             //比较字符串s和p->name,如果返回值为0,代表相等,把p->ID存入数组
        }
        p = p->next;
    }

    return j;                                                   //返回数组中有几个值,即能找到几个联系人
}

修改联系人信息:

#include "struct.h"

void revise( struct node *header )                              //定义修改信息函数
{   
    char c = 0;
    struct node *p = header;
    do
    {
        clear();

        int j = 0;
        int temp = 0;
        int accum = 0;
        int a[20] = {0};
        char name[20] = {0};

        printf("请输入你想修改的联系人的姓名:");
        scanf("%s",name);

        accum = findnum( p, name, a );

        if( accum == 0 )
        {
            printf("此联系人不存在!\n");
        }

        else if( accum == 1 )
        {   
            temp = a[0];
            printfcon( p, temp );
            modify( p, temp );
        }

        else if( accum > 1 )
        {
            printf("有%d个联系人!\n",accum);
            for( j = 0; j < accum; j++ )
            {
                temp = a[j];
                printfcon( p, temp );                           //有不止一个联系人时一个个输出联系人信息,让其修改
                modify( p, temp );
            }
        }       
            printf("是否继续修改? (y/n) :\n");
            __fpurge(stdin);
            c = getchar();

    }while( c == 'y' );                                         //do while语句用来控制是否继续修改,当输入y时继续循环修改
}

int modify( struct node *header, int j )                        //定义修改函数
{
    int temp = 0;
    int rev = 1;
    struct node *p = header;
    while( p->next != NULL )
    {
        p = p->next;
        if( p->ID == j )
        {
            printf("1--姓名\n");
            printf("2--性别\n");
            printf("3--电话\n");
            printf("4--qq号\n");
            printf("5--住址\n");
            printf("6--备注\n");
            printf("请输入你要修改的项:\n");

            do
            {
                rev = 1;
                __fpurge(stdin);
                if(scanf("%d",&temp) != 1)
                {
                    printf("输入错误!请重新输入!\n");
                    rev = -1;
                }
                else if( temp >= 7 || temp <= 0 )
                {
                    printf("输入错误!请重新输入!\n");
                    rev = -1;                                   //当选择的值没有传入或者不为1-6时。输出输入错误请重输
                }
            }while( rev == -1 );

            switch(temp)                                        //用switch语句选择要修改的信息
            {
                case 1:{
                           printf("请输入你要改成的姓名:");
                           scanf("%s",p->name);
                           printf("修改成功!\n");
                           printf("\n");
                           break;
                       }

                case 2:{
                           printf("请输入你要改成的性别:");
                           scanf("%s",p->ismale);
                           printf("修改成功!\n");
                           printf("\n");
                           break;
                       }

                case 3:{
                           printf("请输入你要改成的电话:");
                           scanf("%s",p->tel);
                           printf("修改成功!\n");
                           printf("\n");
                           break;
                       }

                case 4:{
                           printf("请输入你要改成的qq号:");
                           scanf("%s",p->qq);
                           printf("修改成功!\n");
                           printf("\n");
                           break;
                       }

                case 5:{
                           printf("请输入你要改成的住址:");
                           scanf("%s",p->address);
                           printf("修改成功!\n");
                           printf("\n");
                           break;
                       }

                case 6:{
                           printf("请输入你要改成的备注:");
                           scanf("%s",p->remark);
                           printf("修改成功!\n");
                           printf("\n");
                           break;
                       }

                default:printf("输入错误!\n");
                        break;
            }
        }
    }
}

main函数:

#include "struct.h"

void clear()
{
    system("clear");                                    //清屏
}

void interface()                                        //界面函数,输出主界面
{
    printf("            *********************************************************************************\n");
    printf("            *                                                                               *\n");
    printf("        *                                                                                       *\n");
    printf("        |                                                                                       |\n");
    printf("        |                                       通  讯  录                                      |\n");
    printf("        |                                                                                       |\n");
    printf("        |                                    ~~~~~~~~                                   |\n");
    printf("        |                                      1、添加好友;                                     |\n");
    printf("        |                                      2、查看列表;                                     |\n");
    printf("        |                                      3、删除好友;                                     |\n");
    printf("        |                                      4、查找好友;                                     |\n");
    printf("        |                                      5、修改信息;                                     |\n");
    printf("        |                                      6、保存退出;                                     |\n");
    printf("        |                                    ~~~~~~~~                                   |\n");
    printf("        |                                                                                       |\n");
    printf("        |                       请在下面输入1、2、3、4、5、6选择你的操作.                       |\n");
    printf("        |                                                                                       |\n");
    printf("        *                                                                                       *\n");
    printf("            *                                                                               *\n");
    printf("            *********************************************************************************\n");
}

int main()
{
    struct node *header = (struct node *)malloc(sizeof(struct node));   //定义头指针
    if( header == NULL )
    {
        printf("malloc error!\n");
        return -1;
    }
    read_data(header);
    while(1)
    {
        int temp = 0;
        clear();
        interface();                                                    //调用interface函数,输出主界面
        __fpurge(stdin);
        scanf("%d",&temp);

        switch(temp)                                                    //switch语句选择功能
        {
            case 1:{
                       insert_tail( header );
                       printf("按enter返回主界面!\n");
                       __fpurge(stdin);
                       getchar();
                       break;
                   }

            case 2:{
                       list( header );
                       printf("按enter返回主界面!\n");
                       __fpurge(stdin);         
                       getchar();                                       //暂停界面,有输入才退出本次选择语句
                       break;
                   }

            case 3:{
                       mydelete( header );
                       printf("按enter返回主界面!\n");
                       __fpurge(stdin);
                       getchar();
                       break;

                   }

            case 4:{
                       seek( header );
                       printf("按enter返回主界面!\n");
                       __fpurge(stdin);
                       getchar();
                       break;
                   }

            case 5:{
                       revise( header );
                       printf("按enter返回主界面!\n");
                       __fpurge(stdin);
                       getchar();
                       break;
                   }

            case 6:{
                        write_data( header );
                        exit(0);
                    }

            default:{
                        printf("输入错误!");
                        printf("按enter返回主界面!\n");
                        __fpurge(stdin);
                        getchar();
                        break;
                    }
        }
    }

    return 0;
}
  • 8
    点赞
  • 40
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值