C语言/动态通讯录
创始人
2024-06-02 01:43:28
0

本文使用了malloc、realloc、calloc等和内存开辟有关的函数。


文章目录

前言

二、头文件

三、主界面

四、通讯录功能函数

1.全代码

2.增加联系人

3.删除联系人

4.查找联系人

5.修改联系人

6.展示联系人

7.清空联系人

8.退出通讯录

总结


前言

为了使用通讯录时,可以随时调整大小,所以使用动态开辟内存函数写通讯录,可增加联系人容量。

动态开辟函数,即在内存的栈区开辟空间,所以使用完毕后,需要释放内存空间。


一、通讯录运行图

二、头文件

#include
#include
#include
#include
#include#define Max 10enum function
{quit,increase,delete,find,revise,show,empty,sort
};typedef struct Person
{char name[20];size_t age;char sex[5];char address[30];char phone[12];
}person;//动态
typedef struct contact
{person *per;size_t sz;//通讯录已有人员个数size_t ContactMax;//通讯录当前最大容量
}contact;void init_contact(contact* con);void increase_contact(contact* con);void delete_contact(contact* con);//return -1(no) / address(yes)
int find1(const contact** con, size_t choice);
void find_contact(const contact* con);void revise_contact(contact* con);void show_contact(const contact* con);
//排序通讯录
void sort_contact(contact* con);
//销毁通讯录
void destroy_contact(contact* con);

三、主界面

#include "contact.h"void menu1()
{printf("**************************************\n");printf("******* Simplified address book ******\n");printf("*******   1> increase contact   ******\n");printf("*******   2> delete contact     ******\n");printf("*******   3> find contact       ******\n");printf("*******   4> revise contact     ******\n");printf("*******   5> Show all contacts  ******\n");printf("*******   6> Empty all contacts ******\n");printf("*******   7> Sort by name       ******\n");printf("*******   0> Quit Contacts      ******\n");printf("**************************************\n");
}void test()
{//create contactscontact con;//initialize contactsinit_contact(&con);size_t choice = 0;do{menu1();printf("Enter the feature options you need:");scanf("%u", &choice);switch (choice){case increase:increase_contact(&con);break;case delete:delete_contact( &con );break;case find:find_contact(&con);break;case revise:revise_contact(&con);break;case show:show_contact(&con);break;case empty:init_contact(&con);break;case sort:sort_contact(&con);break;case quit:destroy_contact(&con);printf("Exiting Contacts...\n");break;default:printf("You entered the wrong number, please re-enter it.\n");break;}} while (choice);printf("Exited Contacts.\n");}int main()
{test();return 0;
}

四、通讯录功能函数

1.全代码

#include"contact.h"void menu2()
{system("cls");printf("1> name \t 2> age\n");printf("3> sex \t 4> address\n");printf("5> phone\n");printf("Please select:");
}//动态
void init_contact(contact* con)
{assert(con);// per    sz ContactMaxcon->sz = 0;person* p = (person*)calloc(Max, sizeof(person));if (p == NULL){perror("init_contact::calloc");return;}con->per = p;con->ContactMax = Max;
}void tune(contact* con)
{if (con->sz == con->ContactMax){person *p = (person *)realloc(con->per, (con->ContactMax + Max) * sizeof(person));if (p == NULL){perror("tune::realloc");return;}con->per = p;con->ContactMax += Max;}
}//动态开辟
void increase_contact(contact* con)
{assert(con);//检测当前通讯录是否需要增容tune(con);printf("name:");scanf("%s", &(con->per[con->sz].name));printf("age:");scanf("%u", &(con->per[con->sz].age));printf("sex:");scanf("%s", &(con->per[con->sz].sex));printf("address:");scanf("%s", &(con->per[con->sz].address));printf("phone:");scanf("%s", &(con->per[con->sz].phone));(con->sz)++;
}void delete_contact(contact* con)
{assert(con);menu2();size_t choice = 0;size_t result = 0;while (1){scanf("%u", &choice);if (choice <= 5 && choice >= 1){result = find1(&con, choice);break;}else{printf("Your input is incorrect, please re-enter it:");}}if (result != -1){char true[5] = { 0 };printf("Are you sure you want to delete %s's information?", &con->per[result].name);printf("yes/no:");scanf("%s", &true);if (!strcmp(true, "yes")){if ( con->sz ){memmove(con->per[result].name, con->per[(con->sz) - 1].name, sizeof(con->per[0]));}else{memset(con->per[result].name, 0, sizeof(con->per[0]));}(con->sz)--;printf("The deletion was successful, thanks for using!\n");          }else{printf("Delete failed, please try again!\n");}}else{printf("Delete failed, please try again!\n");}
}int find1(const contact** con, size_t choice)
{assert(con);size_t i = 0;char sample1[30] = { 0 };size_t sample2 = 0;printf("Please enter:");switch (choice){case 1:case 3:case 4:case 5:scanf("%s", &sample1);break;case 2:scanf("%u", &sample2);break;}switch (choice){case 1:while (i < (*con)->sz){if (!strcmp(sample1, (*con)->per[i].name)){return i;}else{i++;}}break;case 3:while (i < (*con)->sz){if (!strcmp(sample1, (*con)->per[i].sex)){return i;}else{i++;}}break;case 4:while (i < (*con)->sz){if (!strcmp(sample1, (*con)->per[i].address)){return i;}else{i++;}}break;case 5:while (i < (*con)->sz){if (!strcmp(sample1, (*con)->per[i].phone)){return i;}else{i++;}}break;case 2:while (i < (*con)->sz){if (sample2 == (*con)->per[i].age){return i;}else{i++;}}break;}return -1;
}void find_contact(const contact* con)
{assert(con);menu2();size_t choice = 0;size_t result = 0;while (1){scanf("%u", &choice);if (choice <= 5 && choice >= 1){result = find1(&con, choice);break;}else{printf("Your input is incorrect, please re-enter it:");}}if (result != -1){printf("Found, the basic information of the contact is:");printf("name:%-20s\tage:%-4d\tsex:%-5s\taddress:%-30s\tphone:%-12s\n",con->per[result].name,con->per[result].age,con->per[result].sex,con->per[result].address,con->per[result].phone);}else{printf("Didn't find it!\n");}}void revise_contact(contact* con)
{assert(con);menu2();size_t choice = 0;size_t result = 0;while (1){scanf("%u", &choice);if (choice <= 5 && choice >= 1){result = find1(&con, choice);break;}else{printf("Your input is incorrect, please re-enter it:");}}if (result != -1){char true[5] = { 0 };printf("Are you sure you want to revise %s's information?", &con->per[result].name);printf("yes/no:");scanf("%s", &true);if (!strcmp(true, "yes")){menu2();printf("Please enter the option you want to modify:");scanf("%u", &choice);char sample1[30] = { 0 };size_t sample2 = 0;printf("Please enter:");switch (choice){case 1:case 3:case 4:case 5:scanf("%s", &sample1);break;case 2:scanf("%u", &sample2);break;}switch (choice){case 1:memmove(con->per[result].name, sample1, sizeof(con->per[0].name));break;case 3:memmove(con->per[result].name, sample1, sizeof(con->per[0].sex));break;case 4:memmove(con->per[result].name, sample1, sizeof(con->per[0].address));break;case 5:memmove(con->per[result].name, sample1, sizeof(con->per[0].phone));break;case 2:con->per[result].age = sample2;break;}printf("The modification is complete, thanks for using!\n");}else{printf("Revise failed, please try again!\n");}}else{printf("Revise failed, please try again!\n");}
}void show_contact(const contact* con)
{assert(con);if ( con->sz ){size_t i = 0;for (; i < (con->sz); i++){printf("name:%-20s\tage:%-4d\tsex:%-5s\taddress:%-30s\tphone:%-12s\n",con->per[i].name, con->per[i].age, con->per[i].sex,con->per[i].address, con->per[i].phone);}}else{printf("There is no contact information in the address book!\n");}
}int cmp_char(const void* str1, const void* str2)
{return strcmp(((person*)str1)->name, ((person*)str2)->name);
}void sort_contact(contact* con)
{qsort(con -> per[0].name, con -> sz, sizeof(con -> per[0]), cmp_char);
}void destroy_contact(contact* con)
{free(con->per);con->per = NULL;con->ContactMax = 0;con->sz = 0;con = NULL;
}

2.增加联系人

使用realloc()调整通讯录大小。

联系人信息图为:

void tune(contact* con)
{if (con->sz == con->ContactMax){person *p = (person *)realloc(con->per, (con->ContactMax + Max) * sizeof(person));if (p == NULL){perror("tune::realloc");return;}con->per = p;con->ContactMax += Max;}
}//动态开辟
void increase_contact(contact* con)
{assert(con);//检测当前通讯录是否需要增容tune(con);printf("name:");scanf("%s", &(con->per[con->sz].name));printf("age:");scanf("%u", &(con->per[con->sz].age));printf("sex:");scanf("%s", &(con->per[con->sz].sex));printf("address:");scanf("%s", &(con->per[con->sz].address));printf("phone:");scanf("%s", &(con->per[con->sz].phone));(con->sz)++;
}

3.删除联系人

通过选择联系人的某种信息(例如姓名、年龄)来查找需要删除的联系人,找到之后确认删除该联系人。

例如:

void delete_contact(contact* con)
{assert(con);menu2();size_t choice = 0;size_t result = 0;while (1){scanf("%u", &choice);if (choice <= 5 && choice >= 1){result = find1(&con, choice);break;}else{printf("Your input is incorrect, please re-enter it:");}}if (result != -1){char true[5] = { 0 };printf("Are you sure you want to delete %s's information?", &con->per[result].name);printf("yes/no:");scanf("%s", &true);if (!strcmp(true, "yes")){if ( con->sz ){memmove(con->per[result].name, con->per[(con->sz) - 1].name, sizeof(con->per[0]));}else{memset(con->per[result].name, 0, sizeof(con->per[0]));}(con->sz)--;printf("The deletion was successful, thanks for using!\n");          }else{printf("Delete failed, please try again!\n");}}else{printf("Delete failed, please try again!\n");}
}

4.查找联系人

通过联系人基础信息查找联系人。

int find1(const contact** con, size_t choice)
{assert(con);size_t i = 0;char sample1[30] = { 0 };size_t sample2 = 0;printf("Please enter:");switch (choice){case 1:case 3:case 4:case 5:scanf("%s", &sample1);break;case 2:scanf("%u", &sample2);break;}switch (choice){case 1:while (i < (*con)->sz){if (!strcmp(sample1, (*con)->per[i].name)){return i;}else{i++;}}break;case 3:while (i < (*con)->sz){if (!strcmp(sample1, (*con)->per[i].sex)){return i;}else{i++;}}break;case 4:while (i < (*con)->sz){if (!strcmp(sample1, (*con)->per[i].address)){return i;}else{i++;}}break;case 5:while (i < (*con)->sz){if (!strcmp(sample1, (*con)->per[i].phone)){return i;}else{i++;}}break;case 2:while (i < (*con)->sz){if (sample2 == (*con)->per[i].age){return i;}else{i++;}}break;}return -1;
}void find_contact(const contact* con)
{assert(con);menu2();size_t choice = 0;size_t result = 0;while (1){scanf("%u", &choice);if (choice <= 5 && choice >= 1){result = find1(&con, choice);break;}else{printf("Your input is incorrect, please re-enter it:");}}if (result != -1){printf("Found, the basic information of the contact is:");printf("name:%-20s\tage:%-4d\tsex:%-5s\taddress:%-30s\tphone:%-12s\n",con->per[result].name,con->per[result].age,con->per[result].sex,con->per[result].address,con->per[result].phone);}else{printf("Didn't find it!\n");}}

5.修改联系人

先查找,再修改。

可以修改联系人的任一信息。

void revise_contact(contact* con)
{assert(con);menu2();size_t choice = 0;size_t result = 0;while (1){scanf("%u", &choice);if (choice <= 5 && choice >= 1){result = find1(&con, choice);break;}else{printf("Your input is incorrect, please re-enter it:");}}if (result != -1){char true[5] = { 0 };printf("Are you sure you want to revise %s's information?", &con->per[result].name);printf("yes/no:");scanf("%s", &true);if (!strcmp(true, "yes")){menu2();printf("Please enter the option you want to modify:");scanf("%u", &choice);char sample1[30] = { 0 };size_t sample2 = 0;printf("Please enter:");switch (choice){case 1:case 3:case 4:case 5:scanf("%s", &sample1);break;case 2:scanf("%u", &sample2);break;}switch (choice){case 1:memmove(con->per[result].name, sample1, sizeof(con->per[0].name));break;case 3:memmove(con->per[result].name, sample1, sizeof(con->per[0].sex));break;case 4:memmove(con->per[result].name, sample1, sizeof(con->per[0].address));break;case 5:memmove(con->per[result].name, sample1, sizeof(con->per[0].phone));break;case 2:con->per[result].age = sample2;break;}printf("The modification is complete, thanks for using!\n");}else{printf("Revise failed, please try again!\n");}}else{printf("Revise failed, please try again!\n");}
}

6.展示联系人

展示所有联系人及其所有信息。

void show_contact(const contact* con)
{assert(con);if ( con->sz ){size_t i = 0;for (; i < (con->sz); i++){printf("name:%-20s\tage:%-4d\tsex:%-5s\taddress:%-30s\tphone:%-12s\n",con->per[i].name, con->per[i].age, con->per[i].sex,con->per[i].address, con->per[i].phone);}}else{printf("There is no contact information in the address book!\n");}
}

7.清空联系人

又名初始化通讯录。

重新向内存申请一片空间,存储联系人信息。

void init_contact(contact* con)
{assert(con);// per    sz ContactMaxcon->sz = 0;person* p = (person*)calloc(Max, sizeof(person));if (p == NULL){perror("init_contact::calloc");return;}con->per = p;con->ContactMax = Max;
}

8.退出通讯录

通过free()释放内存栈区的空间,避免内存泄露。

void destroy_contact(contact* con)
{free(con->per);con->per = NULL;con->ContactMax = 0;con->sz = 0;con = NULL;
}

总结

在使用完内存函数之后,一定一定要记得释放空间哦~

上述代码展示就是整个动态通讯录的全部啦,如果你有兴趣想要了解,可以通过C_Ccpp/C_study/contact at main · Yjun6/C_Ccpp (github.com)找到它们。

相关内容

热门资讯

Python|位运算|数组|动... 目录 1、只出现一次的数字(位运算,数组) 示例 选项代...
张岱的人物生平 张岱的人物生平张岱(414年-484年),字景山,吴郡吴县(今江苏苏州)人。南朝齐大臣。祖父张敞,东...
西游西后传演员女人物 西游西后传演员女人物西游西后传演员女人物 孙悟空 六小龄童 唐僧 徐少华 ...
名人故事中贾岛作诗内容简介 名人故事中贾岛作诗内容简介有一次,贾岛骑驴闯了官道.他正琢磨着一句诗,名叫《题李凝幽居》全诗如下:闲...
和男朋友一起优秀的文案? 和男朋友一起优秀的文案?1.希望是惟一所有的人都共同享有的好处;一无所有的人,仍拥有希望。2.生活,...
戴玉手镯的好处 戴玉手镯好还是... 戴玉手镯的好处 戴玉手镯好还是碧玺好 女人戴玉?戴玉好还是碧玺好点佩戴手镯,以和田玉手镯为佳!相嫌滑...
依然什么意思? 依然什么意思?依然(汉语词语)依然,汉语词汇。拼音:yī    rán基本解释:副词,指照往常、依旧...
高尔基的散文诗 高尔基的散文诗《海燕》、《大学》、《母亲》、《童年》这些都是比较出名的一些代表作。
心在飞扬作者简介 心在飞扬作者简介心在飞扬作者简介如下。根据相关公开资料查询,心在飞扬是一位优秀的小说作者,他的小说作...
卡什坦卡的故事赏析? 卡什坦卡的故事赏析?讲了一只小狗的故事, 我也是近来才读到这篇小说. 作家对动物的拟人描写真是惟妙...
林绍涛为简艾拿绿豆糕是哪一集 林绍涛为简艾拿绿豆糕是哪一集第三十二集。 贾宽认为是阎帅间接导致刘映霞住了院,第二天上班,他按捺不...
小爱同学是女生吗小安同学什么意... 小爱同学是女生吗小安同学什么意思 小爱同学,小安同学说你是女生。小安是男的。
内分泌失调导致脸上长斑,怎么调... 内分泌失调导致脸上长斑,怎么调理内分泌失调导致脸上长斑,怎么调理先调理内分泌,去看中医吧,另外用好的...
《魔幻仙境》刺客,骑士人物属性... 《魔幻仙境》刺客,骑士人物属性加点魔幻仙境骑士2功1体质
很喜欢她,该怎么办? 很喜欢她,该怎么办?太冷静了!! 太理智了!爱情是需要冲劲的~不要考虑着考虑那~否则缘...
言情小说作家 言情小说作家我比较喜欢匪我思存的,很虐,很悲,还有梅子黄时雨,笙离,叶萱,还有安宁的《温暖的玄》 小...
两个以名人的名字命名的风景名胜... 两个以名人的名字命名的风景名胜?快太白楼,李白。尚志公园,赵尚志。
幼儿教育的代表人物及其著作 幼儿教育的代表人物及其著作卡尔威特的《卡尔威特的教育》,小卡尔威特,他儿子成了天才后写的《小卡尔威特...
海贼王中为什么说路飞打凯多靠霸... 海贼王中为什么说路飞打凯多靠霸气升级?凯多是靠霸气升级吗?因为之前刚到时确实打不过人家因为路飞的实力...
运气不好拜财神有用吗运气不好拜... 运气不好拜财神有用吗运气不好拜财神有没有用1、运气不好拜财神有用。2、拜财神上香前先点蜡烛,照亮人神...