【C语言】通讯录的实现及本地保存

通讯录的实现,具有本地保存功能

也没什么需要说明的,注释完整,本想再集成一个本地联系人文件加密的,胳膊疼,就不多写了。

环境:Ubuntu18.04下GCC通过编译,就是需要修改一下首页显示格式
			 CLion编译执行完美
			 windows下使用的话,需要更改一下路径转义字符
			 
			共计750多行,耐心点......
			底部附带两张运行界面图,需要图形界面的话用这套个壳就行了

/******************************************************************
 * Project Name: 通讯录
 * By:JP_Shame
 * TIME:20190815---20190816
 ******************************************************************
 * Function:
 * 1.mianPage();
 * 2.void selectFunction();
 * 3.void loadContactFile();
 * 4.void findContact();
 * 5.void creatContact();
 * 6.void deleteContact();
 * 7.void updateContact();
 * 8.void destroyContact();
 * 9.void findAllContact();
 * 10.int scanContactFile();
 * 11.int getContactLines();
 * 12.int main(void);
 * 13.void freeSpace();
 *****************************************************************/

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

//联系人信息结构体
typedef struct contact {
    char *name;
    char *number;
    char *addr;
} Contact;

//两个全局变量,后期使用
Contact *person = NULL;
Contact *allPerson = NULL;

//首页
void mainPage() {
    printf("*********************************\n");
    printf("*\t\t\t 联系人管理\t\t\t*\n");
    printf("*\t\t\t\t\t\t\t\t*\n");
    printf("*\t\t\t1.查找联系人\t\t\t*\n");
    printf("*\t\t\t2.新增联系人\t\t\t*\n");
    printf("*\t\t\t3.删除联系人\t\t\t*\n");
    printf("*\t\t\t4.修改联系人\t\t\t*\n");
    printf("*\t\t\t5.清空联系人\t\t\t*\n");
    printf("*\t\t\t6.所有联系人\t\t\t*\n");
    printf("*\t\t\t0.退出该程序\t\t\t*\n");
    printf("*********************************\n");
}


//获取联系人个数,本可以直接调用形参避免再次增加文件进程,为了后期使用便利重新打开
int getContactLines() {
    FILE *file = fopen("./Contact.txt", "r");

    if (!file) {
        printf("获取通讯录个数时载入失败\n");
        return -1;
    }

    //临时辅助指针
    char *temp = (char *) malloc(sizeof(char) * 1024);
    if (!temp)
        return -1;

    //个数累计变量
    int line = 0;

    //挨行读取
    while (fgets(temp, 1024, file)) {
        line++;
        //临时指针空间清零
        memset(temp, 0, 1024);
    }

    //释放临时指针
    free(temp);
    temp = NULL;
    fclose(file);
    return line;
}


//加载联系人文件到堆区
void loadContactFile() {

    //获取联系人个数,开辟对应大小堆空间
    int line = getContactLines();
    //查找联系人
    FILE *file = fopen("./Contact.txt", "r");

    if (!file) {
        printf("查找联系人时通讯录载入失败\n");
        return;
    }
    allPerson = malloc(sizeof(Contact) * line);

    if (!allPerson)
        return;

    //信息临时储存地
    char *information = (char *) malloc(sizeof(char) * 1024);

    if (!information) {
        return;
    }

    //临时承载器皿,用数组便于度量字符串长度
    char tname[31] = {0};
    char tnum[20] = {0};
    char taddr[61] = {0};

    //作为二级指针数组下标使用
    int i = 0;

    //开始读取
    while (fgets(information, 1024, file)) {
        //printf("%s\n", information);

        //格式化放入临时空间
        sscanf(information, "%[^#]#%[^#]#%s", tname, tnum, taddr);

        //printf("%ld\n", strlen(tname) + 1);

        //动态开辟结构体内部成员空间,不会造成空间浪费
        allPerson[i].name = (char *) malloc(sizeof(char) * strlen(tname) + 1);
        allPerson[i].number = (char *) malloc(sizeof(char) * strlen(tnum) + 1);
        allPerson[i].addr = (char *) malloc(sizeof(char) * strlen(taddr) + 1);

        //将数组中临时信息拷贝到指定堆区中
        strcpy(allPerson[i].name, tname);
        strcpy(allPerson[i].number, tnum);
        strcpy(allPerson[i].addr, taddr);

        //打印测试
        //printf("%s\n%s\n%s\n\n", allPerson[i].name, allPerson[i].number, allPerson[i].addr);

        //保证不会污染
        memset(information, 0, 1024);

        //下标后移
        i++;
    }
    //printf("查找联系人姓名:\n");

    //接收用户查找人信息
    //char *temp = (char*)malloc(sizeof(char)*31);
    //scanf("%s",temp);
    fclose(file);
    free(information);
    information = NULL;

}


//查找联系人
void findContact() {

    //获取联系人个数
    int line = getContactLines();

    //输入提示
    printf("输入联系人姓名:\n");

    //用户输入承载空间
    char *findname = malloc(sizeof(char) * 31);
    scanf("%s", findname);

    //遍历对比
    for (int i = 0; i < line; ++i) {

        //strcmp对比,找到情况下
        if (!strcmp(findname, allPerson[i].name)) {
            printf("找到了\n");
            printf("姓名:%s\n号码:%s\n地址:%s\n\n", allPerson[i].name, allPerson[i].number, allPerson[i].addr);

            //页面暂停,阻塞,一个过滤回车,一个阻塞
            printf("按任意键返回首页\n");
            //system("pause");
            getchar();
            getchar();
            return;
        }
    }

    //未找到
    printf("该联系人不存在\n");

    //系统阻塞,一个过滤回车,一个阻塞
    printf("按任意键返回首页\n");
    getchar();
    getchar();
    return;

}


//添加联系人
void creatContact() {

    //以只写权限打开文件
    FILE *file = fopen("./Contact.txt", "a+");

    if (!file)
        return;

    //存储信息中介,为了实现是否确认添加该联系人
    person = (Contact *) malloc(sizeof(Contact));
    person->name = (char *) malloc(sizeof(char) * 31);
    person->number = (char *) malloc(sizeof(char) * 15);
    person->addr = (char *) malloc(sizeof(char) * 51);

    while (1) {
        //用户输入信息
        printf("在此输入姓名:\n");
        scanf("%s", person->name);
        printf("在此输入号码:\n");
        scanf("%s", person->number);
        printf("在此输入地址:\n");
        scanf("%s", person->addr);

        //用户确认是否添加该信息
        printf("是否将此人添加至本地联系人列表?(是)Y/(否)N\n");

        //过滤回车字符
        getchar();

        //确认字符接收
        char sel;
        scanf("%c", &sel);

        //确认存储该信息,每个联系人信息占一行,用**隔开,便于提取
        if (sel == 'Y') {
            fputs(person->name, file);
            fputs("#", file);
            fputs(person->number, file);
            fputs("#", file);
            fputs(person->addr, file);
            fputs("\n", file);

            //联系人信息确认预览
            printf("%s  %s  %s\n", person->name, person->number, person->addr);

            //rewind(file);
            //printf("%s%s%s",)

            printf("已将联系人添加至本地库,是否继续?(是)Y/(否)N\n");
            getchar();
            scanf("%c", &sel);

            //信息接收指针清零
            memset(person->name, 0, 31);
            memset(person->number, 0, 15);
            memset(person->addr, 0, 51);

            //继续添加联系人
            if (sel == 'Y') {
                fclose(file);
                creatContact();
                return;
            }

                //退出该功能
            else if (sel == 'N') {
                fclose(file);
                printf("已退出添加联系人功能\n");
                return;
            }

                //指令错误情况下退出该功能
            else {
                printf("指令有误,退出该功能\n");
                fclose(file);
                return;
            }
        }

            //不添加该联系人信息
        else if (sel == 'N') {

            //询问是否继续
            printf("已将此人记录销毁,是否继续?(是)Y/(否)N\n");
            getchar();
            scanf("%c", &sel);

            //继续添加联系人,递归处理
            if (sel == 'Y') {
                fclose(file);
                creatContact();
                return;
            }

                //不再添加,则退出
            else if (sel == 'N') {
                fclose(file);
                printf("已退出添加联系人功能\n");
                return;
            }

                //指令错误处理
            else {
                printf("指令有误,退出该功能\n");
                fclose(file);
                return;
            }
        }

            //用户首次进入该功能时,指令输入错误处理
        else {
            printf("已退出添加联系人功能\n");
            fclose(file);
            return;
        }
    }
}


//删除联系人
void deleteContact() {
    loadContactFile();
    //获取联系人个数
    int line = getContactLines();

    //输入提示
    printf("输入联系人姓名:\n");

    //用户输入承载空间
    char *findname = malloc(sizeof(char) * 31);
    scanf("%s", findname);

    //遍历对比
    for (int i = 0; i < line; ++i) {

        //strcmp对比,找到情况下
        if (!strcmp(findname, allPerson[i].name)) {
            printf("找到了\n");

            //再次确认
            printf("姓名:%s\n号码:%s\n地址:%s\n\n", allPerson[i].name, allPerson[i].number, allPerson[i].addr);
            printf("确认删除?无法恢复!(是)Y/(否)任意键\n");

            //阻塞
            getchar();
            char sel;

            //接收指令符
            scanf("%c", &sel);

            //确认删除
            if (sel == 'Y') {
                //重新载入文件,进行覆盖读写
                FILE *fp = fopen("./Contact.txt", "w");
                //char *information = (char*)malloc(sizeof(char)*1024);

                //循环进行读写
                for (int j = 0; j < line - 1; ++j) {

                    //过滤要删除的成员信息
                    if (i == j)
                        continue;

                    //重新写入文件
                    fprintf(fp, "%s#%s#%s\n", allPerson[j].name, allPerson[j].number, allPerson[j].addr);
                }

                //关闭文件以及提示
                fclose(fp);
                printf("该联系人已删除\n");
                printf("按任意键返回首页\n");
                getchar();
                getchar();
                return;
            }

            //用户查找到信息不想删除了,提示带阻塞
            //页面暂停,阻塞,一个过滤回车,一个阻塞
            printf("操作已撤销\n");
            printf("按任意键返回首页\n");
            getchar();
            getchar();
            return;
        }
    }

    //用户输入姓名,未找到情况下
    printf("未找到该联系人\n");
    printf("按任意键返回首页\n");
    getchar();
    getchar();
    return;
}


//修改联系人
void updateContact() {
    //获取联系人个数
    int line = getContactLines();

    //输入提示
    printf("输入联系人姓名:\n");

    //用户输入承载空间
    char *findname = malloc(sizeof(char) * 31);
    scanf("%s", findname);

    FILE *fp = fopen("./Contact.txt", "w");

    //遍历对比
    for (int i = 0; i < line; ++i) {

        //strcmp对比,找到情况下
        if (!strcmp(findname, allPerson[i].name)) {
            printf("找到了\n");
            printf("姓名:%s\n号码:%s\n地址:%s\n\n", allPerson[i].name, allPerson[i].number, allPerson[i].addr);

            //提供选项
            printf("输入要修改的内容选项:\n");
            printf("1.姓名  2.号码  3.地址\n");

            //阻塞
            getchar();

            //选项输入
            int sel;
            scanf("%d", &sel);

            //临时指针空间
            char *temp = malloc(sizeof(char) * 51);

            //提示信息,并进行临时存储
            printf("修改后的内容为:\n");
            scanf("%s", temp);

            //根据选项进行修改
            switch (sel) {

                case 1: {
                    strcpy(allPerson[i].name, temp);
                    for (int j = 0; j < line; j++) {
                        //重新写入文件
                        fprintf(fp, "%s#%s#%s\n", allPerson[j].name, allPerson[j].number, allPerson[j].addr);
                    }
                    printf("***修改成功***\n");
                    break;
                }

                case 2: {
                    strcpy(allPerson[i].number, temp);
                    for (int j = 0; j < line; j++) {
                        //重新写入文件
                        fprintf(fp, "%s#%s#%s\n", allPerson[j].name, allPerson[j].number, allPerson[j].addr);
                    }
                    printf("***修改成功***\n");
                    break;
                }

                case 3: {
                    strcpy(allPerson[i].addr, temp);
                    for (int j = 0; j < line; j++) {
                        //重新写入文件
                        fprintf(fp, "%s#%s#%s\n", allPerson[j].name, allPerson[j].number, allPerson[j].addr);
                    }
                    printf("***修改成功***\n");
                    break;
                }

                default:
                    printf("指令无效,已退出\n");
                    return;
            }

            //页面暂停,阻塞,一个过滤回车,一个阻塞
            printf("是否继续修改?(是)Y,按任意键返回首页\n");
            getchar();
            getchar();

            //继续选项
            char csel;
            scanf("%c", &csel);

            if (csel == 'Y') {
                fclose(fp);
                updateContact();
                return;
            } else {
                fclose(fp);
                return;
            }
        }
    }

    //未找到
    printf("该联系人不存在\n");

    //系统阻塞,一个过滤回车,一个阻塞
    printf("按任意键返回首页\n");
    getchar();
    getchar();
    return;

}

//销毁通讯录文件(直接清空)
void destroyContact() {
    //重点强调
    printf("危险功能,确认密码:\n");
    getchar();
    int key;
    scanf("%d", &key);

    //核对密钥成功
    if (key == 1234) {
        printf("密码确认,开始清空...\n");

        //与其说是销毁,就是对文件清空,利用'w'完成
        FILE *fp = fopen("./Contact.txt", "w");

        //实时关闭,以便刷新内容
        fclose(fp);
        printf("清空成功!后悔也晚了\n");
        return;
    }

        //密钥错误,直接退出
    else {
        printf("密码不对,滚一边去\n");
        return;
    }
}

//查看所有联系人
void findAllContact() {
    //加载
    loadContactFile();

    //获取联系人个数
    int line = getContactLines();

    //判断库文件是否有联系人
    if (line <= 0) {
        printf("本地库没有联系人,去添加吧!\n");
        printf("按任意键返回首页\n");

        getchar();
        getchar();
        return;
    }
    //遍历对比
    for (int i = 0; i < line; ++i) {
        printf("姓名:%s\n号码:%s\n地址:%s\n\n", allPerson[i].name, allPerson[i].number, allPerson[i].addr);
    }

    printf("*********联系人共%d名", line);

    //页面暂停,阻塞,一个过滤回车,一个阻塞
    printf("按任意键返回首页\n");

    getchar();
    getchar();
    return;
}


//扫描本地通讯录文件,新建或者已存在返回1,文件不存在以及创建失败返回0
int scanContactFile() {

    //搜索本地通讯录文件
    FILE *fp = fopen("./Contact.txt", "r");

    //通讯录文件不存在
    if (!fp) {

        //创建通讯录文件
        printf("电脑中没有通讯录文件,是否创建?(是)Y/(否)N\n");
        printf("请输入:\n");
        char sel;
        scanf("%c", &sel);

        //一级:依据指令创建通讯录
        if (sel == 'Y') {

            //重新引导文件
            fp = fopen("./Contact.txt", "w");

            //文件创建失败
            if (!fp) {
                printf("抱歉,通讯录建立失败,请重新建立!\n");
                return 0;
            }

            //成功提示
            printf("通讯录已建立,请继续操作...\n");
            return 1;
        }

            //一级:不创建通讯录
        else if (sel == 'N') {
            printf("未建立通讯录,无法继续操作!\n");
            printf("再次确认是否创建通讯录文件?(是)Y/(否)N\n");

            //系统阻塞(过滤回车)
            getchar();

            //接收指令
            scanf("%c", &sel);

            //二级:创建文件
            if (sel == 'Y') {

                //二级:重新引导文件
                fp = fopen("./Contact.txt", "w");

                //二级:文件引导失败
                if (!fp) {
                    printf("抱歉,通讯录建立失败,请重新建立!\n");
                    return 0;
                }

                //二级:文件引导成功
                printf("通讯录已建立,请继续操作...\n");
                return 1;
            }

            //一级:文件引导失败
            return 0;
        }

            //一级:指令错误情况下
        else {
            printf("输入无效选项,本次操作取消\n如需重新建立请输入\'Y\',输入其他字符将退出!\n");

            //阻塞
            getchar();
            scanf("%c", &sel);

            //二级:重新引导文件
            if (sel == 'Y') {
                fp = fopen("./Contact.txt", "w");

                //二级:文件引导失败
                if (!fp) {
                    printf("抱歉,通讯录建立失败,请重新建立!\n");
                    return 0;
                }

                //二级:文件引导成功
                printf("通讯录已建立,请继续操作...\n");
                return 1;
            }

                //二级:文件引导失败
            else {
                return 0;
            }
        }
    }

    //关闭文件,避免文件光标错乱,亦可使光标置于文件开头
    fclose(fp);

    //防止野指针
    if (fp)
        fp = NULL;

    //通讯录文件已存在
    return 1;
}


//选择对应功能进行操作
void selectFunction() {
    int fun;
    while (1) {

        //载入首页
        mainPage();

        //扫描本地联系人文件
        int ifo = scanContactFile();

        if (!ifo) {
            printf("Sorry,你不建立文件,我也没办法,再见\n");
            return;
        }

        //提示信息
        printf("输入要进行操作的序号:\n");

        //接收用户选项
        scanf("%d", &fun);

        //程序退出指令
        if (!fun) {
            printf("退出成功\n");
            return;
        }

        //加载
        loadContactFile();
        //进行选项
        switch (fun) {
            case 1:
                findContact();
                break;
            case 2:
                creatContact();
                break;
            case 3:
                deleteContact();
                break;
            case 4:
                updateContact();
                break;
            case 5:
                destroyContact();
                break;
            case 6:
                findAllContact();
                break;
        }
    }
}

//释放全局指针空间
void freeSpace() {
    if (person) {

        free(person->name);
        free(person->number);
        free(person->addr);
        free(person);
        person = NULL;
    }

    if (allPerson) {
        for (int i = 0; i < getContactLines(); ++i) {
            free(allPerson[i].name);
            free(allPerson[i].number);
            free(allPerson[i].addr);
        }
        free(allPerson);
        allPerson = NULL;
    }
}



int main(void) {

    selectFunction();

    freeSpace();

    return 0;
}

【C语言】通讯录的实现及本地保存_第1张图片
【C语言】通讯录的实现及本地保存_第2张图片

你可能感兴趣的:(c语言,文件操作)