C语言大作业——通讯录管理系统

纯新人,大北方某个c9就读(就一个吧,懂得都懂)

大一C语言大作业写了个通讯录,之前在csdn上查的总有这样那样的bug,把我自己的完成版发出来,感觉bug应该会少点,也算稍微有点参考价值吧。

数据结构

链表

功能

在代码里注释了。反正很多就对了,一个大作业总不能要求更多功能吧。

"contact.h"

# ifndef   __CONTACT_H
# define   __CONTACT_H

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include
#pragma comment(lib,"winmm.lib")
#define LEN  sizeof(address_list) //开辟空间

int n=0;//记录通讯录人员人数

typedef struct A
{
    char name[100];//名字
    char sex[10];//性别
    char  age[10];//年纪
    char phone[15];//电话
    char addr[100];//地址
    struct A *next;
} address_list;

void show_feature(void);//菜单函数
address_list * add(address_list *);//添加联系人
address_list * delete1(address_list *);//删除特定联系人
void show_list(address_list *);//显示所有联系人
void find_list(address_list *);//寻找特定联系人
address_list * sort(address_list *);//排序联系人
address_list * clear_list(address_list *);//清除所有联系人
address_list * revision_list(address_list *);//修改特定联系人特定信息
void save_list(address_list *);//保存所有联系人信息
void exit_list();//退出通讯录系统
address_list* read_list(address_list *head);//从文件中读取联系人信息
address_list *add_from_file(address_list *head, FILE *fp);//从文件中读取联系人信息
char *s_gets(char *st, int n);//读一个字符串儿
void search_by_type(address_list *head);//按类别搜索联系人
void ltrim(char *s);//去掉字符串左边儿的空格
void rtrim(char *s);//去掉字符串右边儿的空格
int changecolor(int c);//给字儿一个美丽的颜色
# endif // __CONTACT_H

"contact.c"

#include "contact.h"

int main()
{
    char func[45];
    address_list *p1;
    p1 = (address_list *)malloc(LEN);
    p1->next = NULL;

    PlaySound(TEXT("Loading.wav"), NULL, SND_FILENAME|SND_ASYNC);

    printf("\n");
    printf("\n");
    printf("\n");
    printf("\n");
    printf("\n");
    printf("\n");
    printf("\n");
    printf("\n");
    changecolor(14);
    printf("                                  HELLO!\n");
    changecolor(11);
    printf("                   CONTACT MANAGEMENT SYSTEM V1.14514\n");
    printf("                       by RepenX_0001, 5/29/2021\n");
    printf("                        Special Thanks to Uranus\n");

    do
    {
        system("pause");
        system("cls");

        show_feature();                      //显示菜单
        printf("请选择您要进行的操作:");
        scanf("%s", &func);                  //这里选择了读入%s,以避免scanf特性问题
        fflush(stdin);

        if (strlen(func) == 1)
        {
            switch(func[0])                         //选择对联系人进行的操作
            {
            case '1':
                p1=add(p1);
                break;           //添加联系人信息
            case '2':
                p1=delete1(p1);
                break;           //删除指定联系人信息
            case '3':
                find_list(p1);
                break;           //查找指定联系人信息
            case '4':
                revision_list(p1);
                break;           //修改指定联系人信息
            case '5':
                show_list(p1);
                break;           //显示全部联系人信息
            case '6':
                p1=clear_list(p1);
                p1 = (address_list *)malloc(LEN);
                break;           //清除全部联系人信息
            case '7':
                p1=sort(p1);
                break;           //多种方式排序
            case '8':
                save_list(p1);
                break;           //保存到文件
            case '9':
                read_list(p1);
                break;           //从文件中读取
            case '0':
                search_by_type(p1);
                break;           //按指定类型查找
            case 'E':
                exit_list();
                return 0;        //退出系统
            default:
                printf("选择错误,请重新输入!\n");
                break;
            }
        }
        else
        {
            printf("选择错误,请重新输入!\n");
        }
    }
    while(1);
    return 0 ;
}

//修改选定联系人的信息
address_list * revision_list(address_list *head)
{
    if(n==0)
    {
        printf("通讯录中没有信息,请添加或退出!\n");
        return;
    }
    char j[100],q[100],p[100];
    address_list *A1;
    A1 = (address_list *)malloc(LEN);
    printf("请输入你想要修改的人的姓名:");
    s_gets(j,100);
    A1 = head;
    for (int i=1; i <= n; i++)
    {
        if(!(strcmp(j,A1->name)))
        {
            printf("成功找到 %s 的具体信息:\n", A1->name);
            printf("名字:%s,性别:%s,年龄:%s,电话:%s,地址:%s\n",A1->name,A1->sex,A1->age,A1->phone,A1->addr);
            printf("你想要修改%s的什么信息(name, sex, age, phone, addr):",j);
            scanf("%s",q);
            while((strcmp(q,"name"))&(strcmp(q,"sex"))&(strcmp(q,"age"))&(strcmp(q,"phone"))&(strcmp(q,"addr")))
            {
                printf("请输入正确的想要修改的信息!\n");
                printf("你想要修改%s的什么信息(name, sex, age, phone, addr):",j);
                scanf("%s",q);
            }//判断想要修改的类型是否不存在
            printf("你想要把 %s 的 %s 修改成:",j,q);
            s_gets(p,100);
            if(!(strcmp(q,"name")))
                strcpy(A1->name, p);
            if(!(strcmp(q,"sex")))
                strcpy(A1->sex, p);
            if(!(strcmp(q,"age")))
                strcpy(A1->age, p);
            if(!(strcmp(q,"phone")))
                strcpy(A1->phone, p);
            if(!(strcmp(q,"addr")))
                strcpy(A1->addr, p);
            printf("成功把 %s 的 %s 修改为 %s。\n", j,q,p);
            break;
        }
        else
        {
            if(A1->next == NULL)
                printf("没有找到%s的信息!\n",j);
            A1 = A1->next;
        }
    }
    return head;
}
//清除联系人信息
address_list * clear_list(address_list *head)
{
    if(n==0)
    {
        printf("通讯录中没有信息,请添加或退出!\n");
    }
    else
    {
        head = NULL;
        n = 0;
        printf("已清除全部通讯录信息!!\n");
        return head;
    }
}
//寻找特定联系人信息
void find_list(address_list *head)
{
    if(n==0)
    {
        printf("通讯录中没有信息,请添加或退出!\n");
    }
    else
    {
        char j[100];
        address_list *A1;
        A1 = (address_list *)malloc(LEN);
        printf("请输入你要查找人的姓名:");
        s_gets(j,100);
        A1 = head;
        int cnt = 0;
        for (int i=1; i <= n; i++)
        {
            if( strstr(A1->name,j) != NULL )
            {
                cnt++;
                if(cnt == 1)
                {
                    printf("您查找的可能是以下联系人:\n");
                }
                printf("名字:%s,性别:%s,年龄:%s,电话:%s,地址:%s\n",A1->name, A1->sex,A1->age,A1->phone,A1->addr);
                A1 = A1->next;
                //break;
            }
            else
            {
                if(A1->next == NULL && cnt == 0)
                    printf("没有找到%s的信息\n",j);
                A1 = A1->next;
            }
        }
    }
    //free(A1);
}
//删除某通讯录成员信息
address_list * delete1(address_list *head1)
{
    char j[100];
    int i;
    address_list *p1,*p2,*p3,*p4;
    p1=p2=p3=p4=(address_list *)malloc(LEN);
    if (n == 0)
    {
        printf("通讯录中没有信息,请添加或退出!\n");
        goto END;
    }
    else
    {
        p1=p2=head1;
        p4=head1->next;//p4的作用:当删除的是链表第一个数据时候。
        printf("Please enter the name that you want to delete:");
        s_gets(j,100);
        //遍历链表,寻找要删除的数据
        if(!(strcmp(j,head1->name)))//删除数据是否为第一个链表
        {
            if(n==1)
            {
                head1 = NULL;
                printf("删除成功!\n");
                printf("现在通讯表没有任何信息,请添加或退出!\n");
            }
            else
            {
                head1=p4;
                printf("删除成功!");
            }
        }
        //遍历链表寻找要删除的信息(若p3在第一链,则p2在第二链,p1在第三链)
        for (i=1; i<=n; i++)
        {
            p1=p1->next;
            if(!(strcmp(j,p2->name)))
            {
                p3->next=p2->next;
                printf("删除成功!");
                n--;
                goto END;
            }
            else
            {
                p3=p2;
                p2=p1;
            }
        }
    }
    printf("遍历通讯录,并未发现想要删除的信息!");
END:
    return head1;
}
//按首字母从小到大排序联系人信息
address_list * sort(address_list *head)
{
    if(n == 0)
    {
        printf("没有数据,请添加!\n");
        return head;
    }
    else//能进入下面程序的,n>=2
    {
        char j[100];
        address_list *A1, *A2, *A3;
        A1 = A2 = A3 =(address_list *)malloc(sizeof(address_list));//这里不开辟空间总会导致程序崩溃!
        printf("请选择要排序的方式");
        printf("(name, sex, age, phone, addr):");
        scanf("%s",j);
        if((strcmp(j,"name"))&(strcmp(j,"sex"))&(strcmp(j,"age"))&(strcmp(j,"phone"))&(strcmp(j,"addr")))
        {
            printf("输入有误!请输入正确的想要修改的信息!\n");
            goto END;
        }
        //A1 = A2 = A3 = head;
        if(head->next == NULL)//检测是否只有一组数据
        {
            printf("成功完成排序!\n");
            //show_list(head);
            return head;
        }
        else
        {
            for (int ii=1; ii<=n-1; ii++)
            {
                A1 = head->next;
                A2 = head;
                for (int jj=1; jj<=n-ii; jj++)
                {
                    if(jj == 2)
                    {
                        A3 = head;
                    }
                    if(jj > 2)
                    {
                        A3 = A3->next;
                    }
                    if(!(strcmp(j,"name")))
                    {
                        if(strcmp(A2->name,A1->name)>0)
                            goto Loop;
                        else
                            goto Loop1;
                    }
                    if(!(strcmp(j,"sex")))
                    {
                        if(strcmp(A2->sex,A1->sex)>0)
                            goto Loop;
                        else
                            goto Loop1;
                    }
                    if(!(strcmp(j,"age")))
                    {
                        if(strcmp(A2->age,A1->age)>0)
                            goto Loop;
                        else
                            goto Loop1;
                    }
                    if(!(strcmp(j,"phone")))
                    {
                        if(strcmp(A2->phone,A1->phone)>0)
                            goto Loop;
                        else
                            goto Loop1;
                    }
                    if(!(strcmp(j,"addr")))
                    {
                        if(strcmp(A2->addr,A1->addr)>0)
                            goto Loop;
                        else
                            goto Loop1;
                    }
Loop:
                    {
                        if(jj == 1)
                        {
                            head = head->next;
                        }
                        if(jj >= 2)
                        {
                            A3->next = A1;
                        }
                        A2->next = A1->next;
                        A1->next = A2;
                        A1 = A1->next->next;
                        continue;
                    }
Loop1:
                    {
                        A2 = A1;
                        A1 = A1->next;
                    }
                }
                //show_list(head);
            }
            printf("成功完成排序!\n");
        }
END:
        return head;
    }
}

//添加通讯录成员信息
address_list * add(address_list *head)
{
    if(n==0)
    {
        printf("添加通讯录成员\n");
        printf("请输入名字:");
        s_gets(head->name,100);
        printf("请输入性别:");
        s_gets(head->sex,10);
        printf("请输入年龄:");
        s_gets(head->age,10);
        printf("请输入电话:");
        s_gets(head->phone,15);
        printf("请输入地址:");
        s_gets(head->addr,100);
        printf("添加成功!\n");
        head->next = NULL;
    }
    else
    {
        address_list *p = head;
        while(p->next != NULL)
            p = p->next;
        address_list *A1;
        A1 = (address_list *)malloc(sizeof(address_list));
        printf("\n添加通讯录成员\n");
        printf("请输入名字:");
        s_gets(A1->name,100);
        printf("请输入性别:");
        s_gets(A1->sex,10);
        printf("请输入年龄:");
        s_gets(A1->age,10);
        printf("请输入电话:");
        s_gets(A1->phone,15);
        printf("请输入地址:");
        s_gets(A1->addr,100);
        printf("添加成功!\n");
        A1->next = NULL;
        p->next = A1;
    }
    n++;
    return head;
}

//显示已存在通讯表信息
void show_list(address_list *head)
{
    int i;
    address_list *A1;
    A1 = (address_list *)malloc(sizeof(address_list));//这里不开辟空间总会导致程序崩溃!
    A1 = head;
    if (n == 0)
        printf("没有数据,请添加!\n");
    else
    {
        printf("\n现在通讯录中保存 %d 个人的信息!\n",n);
        for (i=1; i<=n; i++)
        {
            printf("名字:%s,性别:%s,年龄:%s,电话:%s,地址:%s\n", A1->name, A1->sex, A1->age, A1->phone, A1->addr);
            A1 = A1->next;
        }
    }
    //free(A1);
}
//保存联系人信息
void save_list(address_list *head)
{
    if(n==0)
    {
        printf("通讯录中没有信息,请添加或退出!\n");
    }
    else
    {
        address_list *A1;
        A1 = (address_list *)malloc(sizeof(address_list));//这里不开辟空间总会导致程序崩溃!
        A1 = head;
        FILE *fp;//文件指针
        /*文件的打开*/
        char data_list[100];
        printf("请输入想保存的文件名称(需带文件后缀):");
        scanf("%s",data_list);
        fp=fopen(data_list,"w");//fopen打开文件,这个文件可以是当前不存在的。“w”以写入的形式打开,“r”以读的形式打开
        if(fp==NULL) //判断如果文件指针为空
        {
            printf("不能打开文件! " );
            //exit(0);//在以0的形式退出,必须在文件开头有#include ,stdlib 头文件即standard library标准库头文件
        }
        //写入数据
        else
        {
            for (int i=1; i<=n; i++)
            {
                fprintf(fp, "%s %s %s %s %s\n", A1->name, A1->sex, A1->age, A1->phone, A1->addr);
                A1 = A1->next;
            }
            printf("通讯录信息成功保存至 %s 中!\n", data_list);
        }
        //关闭文件
        fclose(fp);
        free(A1);
    }
}


address_list* read_list(address_list *head)
{
    FILE *fp;
    char j[100];

    printf("请输入您想读取的文件(需带后缀):");
    s_gets(j,100);

    if ( (fp = fopen(j, "rt")) == NULL )
    {
        puts("找不到该文件!");
        return;
    }
    else
    {
        head = add_from_file(head, fp);
        puts("读取成功!");
    }

    return head;
}

//读取文件并读入信息
address_list *add_from_file(address_list *head, FILE *fp)
{
    address_list *p = head;
    while(p && p->next != NULL)
        p = p->next;
    address_list *A1;
    A1 = (address_list *)malloc(sizeof(address_list));
    if(fscanf(fp,"%s",A1->name) == EOF)
        return head;
    fscanf(fp,"%s",A1->sex);
    fscanf(fp,"%s",A1->age);
    fscanf(fp,"%s",A1->phone);
    fscanf(fp,"%s",A1->addr);
    A1->next = NULL;
    if(n==0)
    {
        *p = *A1;
    }
    else
    {
        p->next = A1;
        p = p->next;
    }
    n++;

    A1 = (address_list *)malloc(sizeof(address_list));
    while(fscanf(fp,"%s",A1->name) != EOF)
    {
        fscanf(fp,"%s",A1->sex);
        fscanf(fp,"%s",A1->age);
        fscanf(fp,"%s",A1->phone);
        fscanf(fp,"%s",A1->addr);
        A1->next = NULL;
        p->next = A1;
        p = p->next;
        n++;
        A1 = (address_list *)malloc(sizeof(address_list));
    }
    return head;
}

//按类别(性别或年龄)查找联系人
void search_by_type(address_list *head)
{
    if(n==0)
    {
        printf("通讯录中没有信息,请添加或退出!\n");
    }
    else
    {
        char typee[100];
        printf("请选择要搜索的信息");
        printf("(sex, age):");
        scanf("%s",typee);
        if((strcmp(typee,"sex"))&(strcmp(typee,"age")))
        {
            printf("输入有误!请输入正确的想要修改的信息!\n");
            return;
        }

        int flag = 0;
        char j[100];
        address_list *A1;
        A1 = (address_list *)malloc(LEN);
        A1 = head;

        int cnt = 0;

        if(!(strcmp(typee,"sex")))
        {
            printf("您想要查看哪一性别的信息:");
            s_gets(j,100);
            for (int i=1; i <= n; i++)
            {
                if(!(strcmp(j,A1->sex)))
                {
                    flag = 1;
                    cnt++;
                    printf("名字:%s,性别:%s,年龄:%s,电话:%s,地址:%s\n",A1->name, A1->sex,A1->age,A1->phone,A1->addr);
                    A1 = A1->next;
                }
                else
                {
                    if( A1->next == NULL && flag == 0)
                        printf("没有找到%s的信息\n",j);
                    A1 = A1->next;
                }
            }
            printf("共找到%d条信息!\n", cnt);
        }

        if(!(strcmp(typee,"age")))
        {
            printf("您想要查看哪一年龄的信息:");
            s_gets(j,100);
            for (int i=1; i <= n; i++)
            {
                if(!(strcmp(j,A1->age)))
                {
                    cnt++;
                    flag = 1;
                    printf("名字:%s,性别:%s,年龄:%s,电话:%s,地址:%s\n",A1->name, A1->sex,A1->age,A1->phone,A1->addr);
                    A1 = A1->next;
                }
                else
                {
                    if( A1->next == NULL && flag == 0)
                        printf("没有找到%s的信息\n",j);
                    A1 = A1->next;
                }
            }
            printf("共找到%d条信息!\n", cnt);
        }
    }
}

//显示功能
void show_feature(void)
{
    printf("\n     现在通讯录中保存 %d 条信息!\n",n);
    printf("---------------------------------------\n");
    printf("|                                     |\n");
    printf("|        1. 添加        2. 删除       |\n");
    printf("|        3. 查找        4. 修改       |\n");
    printf("|        5. 显示        6. 清空       |\n");
    printf("|        7. 排序        8. 保存       |\n");
    printf("|        9. 读取        0. 分类       |\n");
    printf("|                                     |\n");
    printf("|                E.退出               |\n");
    printf("---------------------------------------\n");
}

//退出通讯录系统
void exit_list()
{
    printf("欢迎您再次使用!");
    printf("\n已成功退出通讯录系统!\n");
}

//读一个字符串儿,并过滤非法字符
char *s_gets(char *st, int n)
{
    char *ret_val;
    char *find;

    ret_val = fgets(st, n, stdin);

    while(strlen(ret_val) == 1 && *ret_val == '\n')
    {
        ret_val = fgets(st, n, stdin);
    }

    ltrim(ret_val);
    rtrim(ret_val);

    return ret_val;
}

//去掉字符串左边儿的空格
void ltrim(char *s)
{
    char *p;
    p = s;
    while(*p == ' ' || *p == '\t')
    {
        *p++;
    }
    strcpy(s,p);
}

//去掉字符串右边儿的空格
void rtrim(char *s)
{
    int i;
    i = strlen(s)-1;

    while((s[i] == '\n' || s[i] == ' ') && i >= 0)
    {
        i--;
    }
    s[i+1] = '\0';
}

//改变文字颜色
int changecolor(int c)
{
    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), c);
    return 0;
}

照抄会被零分然后过程淘汰的哦。规格严格,功夫到家,懂得都懂。

你可能感兴趣的:(c语言)