基于C++实现三种不同版本的通讯录
爱吃折耳根的小黑鱼 人气:0静态版本
这个版本可以说是1.0版,毕竟后面实现都是在它基础上实现改进。所以就它开始开头练手。
这里实现代码大多是语法,并没有太多花里胡哨的,逻辑清晰直接开干。
可以试想一下,对于内容存储,查找无非就是根据他的特征来查找,所以确定需要存储的变量就可以保存实现。通讯录可以简单对于名字,性别,年龄,电话号等来确定查找。
我们使用结构体来进行整体构造,可以用一个结构体作为整个整体框架,框架里还有个人信息保存也需要一个结构来进行内容管理保存。相当于一个大柜子上有很多小抽屉。
有了框架可以直接上代码
test.c
#include"main.h" void menu() { printf("****************************\n"); printf("***1.add 2.del*****\n"); printf("***3.serach 4.modify****\n"); printf("***5.show 6.eixt ****\n"); printf("****************************\n"); } enum option { ADD=1, DEL, SERACH, MODIFY, SHOW, EXIT }; int main() { int input = 0; struct contacts con; init_contact(&con); do { flag: menu(); printf("请选择模式:"); scanf("%d", &input); switch (input) { case ADD: //DestroyContact(&con); addinfo(&con); break; case DEL: delinfo(&con); break; case SERACH: searchinfo(&con); break; case MODIFY: modifyinfo(&con); break; case SHOW: showinfo(&con); break; case EXIT: printf("退出\n"); // DestroyContact(&con); break; default: printf("输入无效\n"); goto flag; break; } } while (input); return 0; }
function.c
#include"main.h" //初始化--静态版 void init_contact(struct contacts* pcon) { assert(pcon); pcon->size = 0; memset(pcon->date, 0, size_num * sizeof(struct self_info)); } //sort int CmpByName(const void* e1,const void* e2) { return strcmp(((struct self_info*)e1)->name, ((struct self_info*)e2)->name); } void SortContact(struct contacts* pcon) { qsort(pcon->date, pcon->size, sizeof(struct self_info), CmpByName); } //1 void addinfo(struct contacts* pcon) { assert(pcon); if (pcon->size == size_num) { printf("The contacts is full\n"); } else { printf("请输入姓名:"); scanf("%s", pcon->date[pcon->size].name); printf("请输入年龄:"); scanf("%d",&(pcon->date[pcon->size].age));//注意取地址 printf("请输入电话:"); scanf("%s", pcon->date[pcon->size].tele); printf("请输入地址:"); scanf("%s", pcon->date[pcon->size].adeer); printf("请输入性别:"); scanf("%s", pcon->date[pcon->size].sex); pcon->size++;//数组下标 printf("operation was successful\n"); } void SortContact(struct contacts* pcon); } // static int find_contactsbyname(const struct contacts* pcon, const char name[]) { int i = 0; for (i = 0; i < pcon->size; i++) { if (0 == strcmp(pcon->date[i].name, name)) { return i; } } return -1; } //2 void delinfo(struct contacts* pcon) { char name[size_num]; printf("输入想要删除的人名:"); scanf("%s", name); int ret=find_contactsbyname(pcon, name); if (ret == -1) { printf("no the people \n"); } else { int j = 0; for (j = ret; j < pcon->size-1; j++) { pcon->date[j] = pcon->date[j + 1]; } pcon->size--; printf("the information was delet\n"); } } //3 void searchinfo(const struct contacts* pcon) { char name[size_num]; scanf("%s", &name); printf("请输入要查找人名:\n"); int ret = find_contactsbyname(pcon, name); if (ret == -1) { printf("no the people \n"); } else { printf("%-20s\t%-2s\t%-20s\t%-40s\t%-6s\n", "姓名", "年龄", "地址", "电话", "性别"); printf("%-20s\t%-2d\t%-20s\t%-40s\t%-6s\n", pcon->date[pcon->size].name, pcon->date[pcon->size].age, pcon->date[pcon->size].adeer, pcon->date[pcon->size].tele, pcon->date[pcon->size].sex); } } //4 void modifyinfo(struct contacts* pcon) { char name[size_num]; scanf("%s", &name); printf("请输入要修改的人名:\n"); int ret = find_contactsbyname(pcon, name); if (ret == -1) { printf("no one"); } else { printf("请输入姓名:"); scanf("%s", pcon->date[ret].name); printf("请输入年龄:"); scanf("%d", &(pcon->date[ret].age));//注意取地址 printf("请输入电话:"); scanf("%s", pcon->date[ret].tele); printf("请输入地址:"); scanf("%s", pcon->date[ret].adeer); printf("请输入性别:"); scanf("%s", pcon->date[ret].sex); printf("修改成功\n"); } } //5 void showinfo(const struct contacts* pcon) { printf("%-20s\t%-5s\t%-20s\t%-20s\t%-6s\n", "姓名", "年龄", "地址", "电话", "性别"); int i = 0; for (i = 0; i <=pcon->size; i++) { if(pcon->date[i].age != 0) printf("%-20s\t %-5d\t %-20s\t %-20s\t %-6s\n", pcon->date[i].name, pcon->date[i].age, pcon->date[i].adeer, pcon->date[i].tele, pcon->date[i].sex); } }
fuction.h
#include<stdio.h> #include<string.h> #include<assert.h> #include<stdlib.h> #include<errno.h> //静态版 #define size_num 100 //信息大小 #define size_name 20 #define size_sex 6 #define size_adeer 20 #define num_tele 12 //个人信息 struct self_info { char name[size_name]; char sex[size_sex]; char tele[num_tele]; int age; char adeer[size_adeer]; }; //静态版本 //struct contacts //{ // struct self_info date[size_num]; // int size; //}; //初始化 void init_contact(struct contacts* pcon); //增加 void addinfo(struct contacts* pcon); //删除 void delinfo(struct contacts* pcon); //查找 int find_contactsbyname(struct contacts* pcon, char* name[]); void searchinfo(const struct contacts* pcon); //展示 void showinfo(const struct contacts* pcon); //修改 void modifyinfo(struct contacts* pcon); //sort void SortContact(struct contacts* pcon);
动态版本
这里我们是在静态版本上升级改动而来,在后面我们实现代码时发现,假如我们输入地址比较详细或者名字太长时间,就需要我们不停更改头文件中内容,所以为了能够减少对于代码修改。所以我们就可以用动态内存开辟。
在function.h中加入
//销毁 void DestroyContact(struct contacts* pcon);
在静态版本function.c中加入
//动态版 //void init_contact(struct contacts* pcon) //{ // assert(pcon); // pcon->date=(struct self_info*)malloc(defalut_size * sizeof(struct self_info)); // if (pcon->date == NULL) // { // perror("init_contact()"); // return; // } // int size = 0; // int capacity = defalut_size; //} // 销毁 //void DestroyContact(struct contacts* pcon) //{ // free(pcon->date); // pcon->date = NULL; // pcon->capacity = 0; // pcon->size = 0; //}
还有函数addinfo前加入,检查开辟空间是否足够,避免越界访问。
//static int chack_capacity(struct contacts* pcon) //{ // if (pcon->size == pcon->capacity) // { // //增容是增加信息 // struct self_info* str = (struct self_info*)realloc(pcon->date, (alterable_size + pcon->capacity) * sizeof(struct self_info)); // if (str != NULL) // { // pcon->date = str; // pcon->capacity += alterable_size; // printf("扩容成功,内存足够,放心使用\n"); // return 1; // } // else // { // perror("chack_capacity()"); // return 0; // } // } // else // { // return 1; // } // //}
便可以实现动态开辟内存。
文件版本
这里可以实现文件形式保存,前面版本是基于程序使用,程序关闭数据也会消失。这里会在对应文件目录下,生成一个txt文本,便于观察。这里需要对于文件操作有一定了解。对于文件写入与输出函数的参数了解和熟悉。本次使用函数有以下函数。
文件打开函数: fopen
文件关闭函数: fclose
二进制输入函数: fwrite
二进制输出函数: fread
代码如下
#define _CRT_SECURE_NO_WARNINGS 1 #include "contact.h" //静态的版本 //void InitContact(struct Contact* pc) //{ // assert(pc); // pc->sz = 0; // memset(pc->data, 0, MAX *sizeof(struct PeoInfo)); //} static int check_capacity(struct Contact* pc); void LoadContact(struct Contact* pc) { //打开文件 FILE*pfR = fopen("data.txt", "rb"); if (pfR == NULL) { perror("LoadContact::fopen"); return; } //读文件 struct PeoInfo tmp = { 0 }; while (fread(&tmp, sizeof(struct PeoInfo), 1, pfR)) { //考虑增加容量的问题 check_capacity(pc); pc->data[pc->sz] = tmp; pc->sz++; } //关闭文件 fclose(pfR); pfR = NULL; } void InitContact(struct Contact* pc) { assert(pc); pc->data = (struct PeoInfo*)malloc(DEFAULT_SZ * sizeof(struct PeoInfo)); if (pc->data == NULL) { perror("InitContact()"); return; } pc->sz = 0; pc->capacity = DEFAULT_SZ; //加载文件中的信息,到通讯录中 LoadContact(pc); } void DestroyContact(struct Contact* pc) { free(pc->data); pc->data = NULL; pc->capacity = 0; pc->sz = 0; } //静态的版本 //void AddContact(struct Contact* pc) //{ // assert(pc); // // if (pc->sz == MAX) // { // printf("通讯录已满,无法添加数据\n"); // return; // } // // //增加人的信息 // printf("请输入名字:>"); // scanf("%s", pc->data[pc->sz].name); // printf("请输入性别:>"); // scanf("%s", pc->data[pc->sz].sex); // printf("请输入年龄:>"); // scanf("%d", &(pc->data[pc->sz].age)); // printf("请输入电话:>"); // scanf("%s", pc->data[pc->sz].tele); // printf("请输入地址:>"); // scanf("%s", pc->data[pc->sz].addr); // // pc->sz++; // printf("成功增加联系人\n"); //} static int check_capacity(struct Contact* pc) { if (pc->sz == pc->capacity) { //增加容量 struct PeoInfo* ptr = (struct PeoInfo*)realloc(pc->data, (pc->capacity + INC_SZ) * sizeof(struct PeoInfo)); if (ptr != NULL) { pc->data = ptr; pc->capacity += INC_SZ; printf("增容成功\n"); return 1; } else { perror("AddContact()"); return 0; } } else return 1; } //动态增长的版本 void AddContact(struct Contact* pc) { assert(pc); if (0 == check_capacity(pc)) { return; } //增加人的信息 printf("请输入名字:>"); scanf("%s", pc->data[pc->sz].name); printf("请输入性别:>"); scanf("%s", pc->data[pc->sz].sex); printf("请输入年龄:>"); scanf("%d", &(pc->data[pc->sz].age)); printf("请输入电话:>"); scanf("%s", pc->data[pc->sz].tele); printf("请输入地址:>"); scanf("%s", pc->data[pc->sz].addr); pc->sz++; printf("成功增加联系人\n"); } void ShowContact(const struct Contact* pc) { int i = 0; printf("%-20s\t%-5s\t%-5s\t%-12s\t%-30s\n", "姓名", "性别", "年龄", "电话", "地址"); for (i = 0; i < pc->sz; i++) { printf("%-20s\t%-5s\t%-5d\t%-12s\t%-30s\n", pc->data[i].name, pc->data[i].sex, pc->data[i].age, pc->data[i].tele, pc->data[i].addr); } } static int FindByName(const struct Contact* pc, char name[]) { int i = 0; for (i = 0; i < pc->sz; i++) { if (0 == strcmp(pc->data[i].name, name)) { return i; } } return -1; } void DelContact(struct Contact* pc) { char name[MAX_NAME]; printf("请输入要删除人的名字:>"); scanf("%s", name); //查找一下指定的人是否存在 int ret = FindByName(pc, name); if (ret == -1) printf("要删除的人不存在\n"); else { //删除 int j = 0; for (j = ret; j < pc->sz - 1; j++) { pc->data[j] = pc->data[j + 1]; } pc->sz--; printf("成功删除指定联系人\n"); } } void SearchContact(const struct Contact* pc) { char name[MAX_NAME]; printf("请输入要查找的人的名字:>"); scanf("%s", name); //查找一下指定的人是否存在 int ret = FindByName(pc, name); if (ret == -1) printf("要查找的人不存在\n"); else { printf("%-20s\t%-5s\t%-5s\t%-12s\t%-30s\n", "姓名", "性别", "年龄", "电话", "地址"); printf("%-20s\t%-5s\t%-5d\t%-12s\t%-30s\n", pc->data[ret].name, pc->data[ret].sex, pc->data[ret].age, pc->data[ret].tele, pc->data[ret].addr); } } void ModifyContact(struct Contact* pc) { printf("请输入要修改人的名字:>"); char name[MAX_NAME]; scanf("%s", name); int ret = FindByName(pc, name); if (ret == -1) printf("要修改的人不存在\n"); else { printf("请输入名字:>"); scanf("%s", pc->data[ret].name); printf("请输入性别:>"); scanf("%s", pc->data[ret].sex); printf("请输入年龄:>"); scanf("%d", &(pc->data[ret].age)); printf("请输入电话:>"); scanf("%s", pc->data[ret].tele); printf("请输入地址:>"); scanf("%s", pc->data[ret].addr); printf("修改成功\n"); } } //int CmpByAge(const void* e1, const void* e2) //{ // return ((struct PeoInfo*)e1)->age - ((struct PeoInfo*)e2)->age; //} // 按照年龄来排序 //void SortContact(struct Contact* pc) //{ // qsort(pc->data, pc->sz, sizeof(struct PeoInfo), CmpByAge); //} int CmpByName(const void* e1, const void* e2) { return strcmp(((struct PeoInfo*)e1)->name, ((struct PeoInfo*)e2)->name); } //按照年龄来排序 void SortContact(struct Contact* pc) { qsort(pc->data, pc->sz, sizeof(struct PeoInfo), CmpByName); } void SaveContact(struct Contact* pc) { //打开文件 FILE* pfW = fopen("data.txt", "wb"); if (pfW == NULL) { perror("SaveContact::fopen"); return; } //写文件 int i = 0; for (i = 0; i < pc->sz; i++) { fwrite(pc->data+i, sizeof(struct PeoInfo), 1, pfW); } //关闭文件 fclose(pfW); pfW = NULL; }
部分函数还需要添加头文件。
对于这个通讯录写入有部分细节需要注意比如动态开辟后,空间是否开辟成功,空间使用后需要关闭,并将指针NULL。文件操作类似。这个通讯录实现后最后也是保存在文件中后期数据较大了,读写较慢耗时。而且数据也不安全,文件保存容易被修改和丢失。后期可以使用数据库实现数据保存。
加载全部内容