通讯录

第一次尝试
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<windows.h>
#define MAX 1000

//通讯录可以用来存储1000个人的信息,每个人的信息包括:姓名、性别、年龄、电话、住址
//1.添加联系人信息
//2.删除指定联系人信息
//3.查找指定联系人信息
//4.修改指定联系人信息
//5.显示所有联系人信息
//6.清空所有联系人
//0.退出
//(以名字排序所有联系人)

//创建联系人结构体
typedef struct preson {
    char name[1024];
    //让用户输入姓名的拼音,用来进行排序
    char namecmp[1024];
    char sex[1024];
    int age;
    char tel[1024];
    char address[1024];
}preson;
//创建通讯录结构体
typedef struct addressBook {
    preson pre[MAX];
    //记录通讯录中当前有效联系人
    int size;
}addressBook;
//初始化通讯录结构体
void initpre(addressBook* addressbook) {
    addressbook->size = 0;
}

//1.添加联系人信息;姓名、性别、年龄、电话、住址
void addpre(addressBook* addressbook) {
    system("cls");
    if (addressbook->size > MAX) {
        printf("通讯录已满!");
        return;
    }
    //printf("1\n");
    printf("添加联系人:\n");
    printf("姓名:");
    scanf("%s", &addressbook->pre[addressbook->size].name);
    printf("姓名的拼音:");
    scanf("%s", &addressbook->pre[addressbook->size].namecmp);
    printf("性别:");
    scanf("%s", &addressbook->pre[addressbook->size].sex);
    printf("年龄:");
    scanf("%d", &addressbook->pre[addressbook->size].age);
    printf("电话:");
    scanf("%s", &addressbook->pre[addressbook->size].tel);
    printf("住址:");
    scanf("%s", &addressbook->pre[addressbook->size].address);
    addressbook->size++;
    for (int i = addressbook->size - 1; i > 0; i--) {
        if (strcmp(addressbook->pre[i - 1].namecmp, addressbook->pre[i].namecmp) > 0) {
            preson p;
            p = addressbook->pre[i];
            addressbook->pre[i] = addressbook->pre[i - 1];
            addressbook->pre[i - 1] = p;
        }
    }
    printf("添加联系人成功!\n");
    Sleep(1000);
}
//2.删除指定联系人信息
void delpre(addressBook* addressbook) {
    //printf("2\n");
    //由于会出现同名同姓的人,因此让用户先输入想要删除的人的姓名
    //将叫这个姓名的全部联系人打印出来,然后让用户选择前面的序号进行删除
    int flag[MAX] = { -1 };
    int j = 0;
    while (1) {
        system("cls");
        printf("请输入要删除联系人的姓名:");
        char name[1024] = { 0 };
        scanf("%s", name);
        for (int i = 0; i < addressbook->size; i++) {
            if (strcmp(addressbook->pre[i].name, name) == 0) {
                printf("[%d]\t\t%s\t\t%s\t\t%d\t\t%s\t\t%s\n", i,
                    addressbook->pre[i].name,
                    addressbook->pre[i].sex,
                    addressbook->pre[i].age,
                    addressbook->pre[i].tel,
                    addressbook->pre[i].address);
                flag[j] = i;
                j++;
            }
        }
        if (flag[0] == -1) {
            printf("未找到要删除的人!\n");
            Sleep(1000);
            continue;
        }
        break;
    }
    while (1) {
        printf("请输入要删除联系人的序号:");
        int num = 0;
        scanf("%d", &num);
        for (int i = 0; i < j; i++) {
            if (flag[i] == num) {
                //数组整体前移,覆盖掉要删除的人
                for (int k = i; k < addressbook->size; k++) {
                    addressbook->pre[k] = addressbook->pre[k + 1];
                }
                addressbook->size--;
                printf("删除联系人成功!\n");
                Sleep(1000);
                return;
            }
        }
        printf("输入的序号有误!\n");

    }
}
//3.查找指定联系人信息
void findpre(addressBook* addressbook) {
    //printf("3\n");
    system("cls");
    int j = 0;
    while (1) {
        printf("请输入要查找联系人的姓名:");
        char name[1024] = { 0 };
        scanf("%s", name);
        for (int i = 0; i < addressbook->size; i++) {
            if (strcmp(addressbook->pre[i].name, name) == 0) {
                printf("[%d]\t\t%s\t\t%s\t\t%d\t\t%s\t\t%s\n", i,
                    addressbook->pre[i].name,
                    addressbook->pre[i].sex,
                    addressbook->pre[i].age,
                    addressbook->pre[i].tel,
                    addressbook->pre[i].address);
                j++;
            }
        }
        if (j == 0) {
            printf("未找到要查找的人!");
            while (1) {
                Sleep(1000);
                system("cls");
                printf("是否重新查找?\n1--是\t2-否\n");
                int choose = 0;
                scanf("%d", &choose);
                if (choose == 1) {
                    break;
                }
                else if (choose == 2) {
                    return;
                }
                else {
                    printf("输入有误!\n");
                    Sleep(1000);
                }
            }
        }
        else {
            printf("按'E'键返回主页\n");
            while (1) {
                char choose = 'c';
                scanf("%c", &choose);
                if (choose == 'E') {
                    return;
                }
            }
        }
    }
}
//4.修改指定联系人信息
void amendpre(addressBook* addressbook) {
    //printf("4\n");
    //由于会出现同名同姓的人,因此让用户先输入想要修改的人的姓名
    //将叫这个姓名的全部联系人打印出来,然后让用户选择前面的序号进行修改
    int flag[MAX] = { -1 };
    int j = 0;
    while (1) {
        system("cls");
        printf("请输入要修改联系人的姓名:");
        char name[1024] = { 0 };
        scanf("%s", name);
        for (int i = 0; i < addressbook->size; i++) {
            if (strcmp(addressbook->pre[i].name, name) == 0) {
                printf("[%d]\t\t%s\t\t%s\t\t%d\t\t%s\t\t%s\n", i,
                    addressbook->pre[i].name,
                    addressbook->pre[i].sex,
                    addressbook->pre[i].age,
                    addressbook->pre[i].tel,
                    addressbook->pre[i].address);
                flag[j] = i;
                j++;
            }
        }
        if (flag[0] == -1) {
            printf("未找到要修改的人!\n");
            Sleep(1000);
            continue;
        }
        break;
    }
    while (1) {
        printf("请输入要修改联系人的序号:");
        int num = 0;
        scanf("%d", &num);
        for (int i = 0; i < j; i++) {
            if (flag[i] == num) {
                //让用户输入修改信息
                printf("修改后姓名:");
                scanf("%s", &addressbook->pre[flag[i]].name);
                printf("修改后姓名的拼音:");
                scanf("%s", &addressbook->pre[flag[i]].namecmp);
                printf("修改后性别:");
                scanf("%s", &addressbook->pre[flag[i]].sex);
                printf("修改后年龄:");
                scanf("%d", &addressbook->pre[flag[i]].age);
                printf("修改后电话:");
                scanf("%s", &addressbook->pre[flag[i]].tel);
                printf("修改后住址:");
                scanf("%s", &addressbook->pre[flag[i]].address);
                int k = i;
                for (int i = flag[k]; i > 0&&i<addressbook->size-1; ) {
                    if (strcmp(addressbook->pre[i - 1].namecmp, addressbook->pre[i].namecmp) > 0) {
                        preson p;
                        p = addressbook->pre[i];
                        addressbook->pre[i] = addressbook->pre[i - 1];
                        addressbook->pre[i - 1] = p;
                        i--;
                    }
                    else if(strcmp(addressbook->pre[i].namecmp, addressbook->pre[i+1].namecmp) > 0){
                        preson p;
                        p = addressbook->pre[i];
                        addressbook->pre[i] = addressbook->pre[i + 1];
                        addressbook->pre[i + 1] = p;
                        i++;
                    }
                    else {
                        break;
                    }
                }
                printf("修改联系人成功!\n");
                Sleep(1000);
                return;
            }
        }
        printf("输入的序号有误!\n");
    }
}
//5.显示所有联系人信息
void showpre(addressBook* addressbook) {
    //printf("5\n");
    system("cls");
    printf("当前同通讯录共有 %d 个联系人\n", addressbook->size);
    printf("序号\t\t姓名\t\t性别\t\t年龄\t\t电话\t\t住址\n");
    for (int i = 0; i < addressbook->size; i++) {
        printf("[%d]\t\t%s\t\t%s\t\t%d\t\t%s\t\t%s\n", i,
            addressbook->pre[i].name,
            addressbook->pre[i].sex ,
            addressbook->pre[i].age,
            addressbook->pre[i].tel,
            addressbook->pre[i].address);
    }
    printf("按'E'键返回主页\n");
    while (1) {
        char choose = 'c';
        scanf("%c", &choose);
        if (choose == 'E') {
            return;
        }
    }
}
//6.清空所有联系人
void emptypre(addressBook* addressbook) {
    //printf("6\n");
    system("cls");
    printf("您真的要删除所有联系人?\n1--返回\t2--确定\n");
    while (1) {
        printf("请选择:");
        int choose = 0;
        scanf("%d", &choose);
        if (choose == 1) {
            return;
        }
        else if (choose == 2) {
            addressbook->size = 0;
            printf("删除成功!");
            Sleep(1000);
            return;
        }
        else {
            printf("输入有误!\n");
        }
    }
}
//0.退出

//打印菜单
int menu() {
    printf("---------------------------\n");
    printf("1.添加联系人\n");
    printf("2.删除指定联系人信息\n");
    printf("3.查找指定联系人信息\n");
    printf("4.修改指定联系人信息\n");
    printf("5.显示所有联系人信息\n");
    printf("6.清空所有联系人\n");
    printf("0.退出\n");
    printf("---------------------------\n");
    printf("请输入你的选择:");
    int choose = 0;
    scanf("%d", &choose);
    return choose;
}
addressBook addressbook;
addressBook* p = &addressbook;
typedef void(*Address)(addressBook*);
int main() {
    //创建一个转移表,省去繁琐的if else结构
    Address address[] = {
        NULL,
        addpre,
        delpre,
        findpre,
        amendpre,
        showpre,
        emptypre
    };
    initpre(p);
    while (1) {
        system("cls");
        int choose = menu();
        if (choose > 6 || choose < 0) {
            printf("输入有误!\n");
            Sleep(1000);
            continue;
        }
        else if (choose == 0) {
            return 0;
        }
        else {
            address[choose](p);
        }
    }
    return 0;
}

反思与总结:

  1. 为了避免名字重复,让用户输入名字后,还要再输入序号,这不够完善,如果没有重名那不就让用户输入的工序复杂了;
  2. 其实每个模块函数结束后,应该让用户选择是返回主菜单还是直接退出程序,只有一小部分做了这一点,还有些没加这一步;
  3. 在修改联系人信息这一模块中,用户必须将选定修改的联系人的所有信息全部修改一遍,没能实现用户选择哪个信息就修改哪个信息;
  4. 在本程序中,对联系人进行按名字排序是让用户输入名字对应的拼音然后实现的,没有调用第三方函数库来实现这一功能,不够好;

但是通讯录的基本功能已经实现,上面所说的问题后续会进行修改的。


博客园发表于 2020-11-23 16:44

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值