• 通讯录(C语言版)


    用c语言实现一个通讯录

    功能:.添加、删除、查找、更改、显示、排序联系人

    内存存储方式:结构体数组

    1.打印菜单,各个功能分别用函数实现,将函数声明放在头文件中。

    2.定义联系人信息,将联系人信息与count(用来记录当前通讯录人数),capacity(记录最大容量)。一起定义到结构体中,完成联系人的创建:

    1. //定义联系人
    2. typedef struct PenInfo {
    3. char name[20];
    4. int age;
    5. char sex[10];
    6. char tele[12];
    7. char addr[30];
    8. }PenInfo;
    9. typedef struct Contact {
    10. PenInfo* data;
    11. int count;
    12. int capacity;//设置我通讯录的最大容量
    13. }Contact;

    3.创建联系人,并用malloc或calloc函数向内存堆区开辟内存,在退出时记得释放内存,将count初始化为0

    1. int Initcontact(Contact* pc) {
    2. assert(pc);
    3. pc->data =(PenInfo*) calloc(3,3 * sizeof(PenInfo));//为data开辟三个空间
    4. if (pc->data == NULL) {
    5. printf("%s", strerror(errno));
    6. return 1;
    7. }
    8. pc->count = 0;
    9. pc->capacity = 3;//设置最大容量为3
    10. //从文件中读取联系人内容
    11. LoadContact(pc);
    12. return 0;
    13. }

    4.添加联系人,当联系人容量达到最大容量时,增容,然后进行联系人的信息输入:

    1. void AddCapacity(Contact *pc) {
    2. assert(pc);
    3. if (pc->count == pc->capacity) {
    4. PenInfo*str=(PenInfo*)realloc(pc->data, (pc->capacity + 2) * sizeof(PenInfo));
    5. if (str == NULL) {
    6. perror("空间不足\n");
    7. return;
    8. }
    9. pc->capacity +=2;
    10. pc->data = str;
    11. //printf("增容成功\n");
    12. }
    13. return;
    14. }
    15. void Addcontact(Contact* pc){
    16. assert(pc);
    17. //增容
    18. AddCapacity(pc);
    19. //添加联系人
    20. printf("请输入联系人名字:>");
    21. scanf("%s", pc->data[pc->count].name);
    22. printf("请输入联系人年龄:>");
    23. scanf("%d", &(pc->data[pc->count].age));
    24. printf("请输入联系人性别:>");
    25. scanf("%s", pc->data[pc->count].sex);
    26. printf("请输入联系人电话:>");
    27. scanf("%s", pc->data[pc->count].tele);
    28. printf("请输入联系人地址:>");
    29. scanf("%s", pc->data[pc->count].addr);
    30. pc->count++;
    31. printf("添加成功\n");
    32. }

    5. 显示联系人(记得格式化)通过for循环标准输出:

    1. void Showcontact(const Contact* pc) {
    2. assert(pc);
    3. if (pc->count == 0) {
    4. printf("还没添加联系人\n");
    5. return;
    6. }
    7. printf("%-20s\t%-3s\t%-10s\t%-12s\t%-30s\n", "名字", "年龄", "性别", "电话", "地址");
    8. printf("-----------------------------------------------------------------------------\n");
    9. for (int i = 0; i < pc->count; i++) {
    10. printf("%-20s\t%-5d\t%-10s\t%-12s\t%-30s", pc->data[i].name,
    11. pc->data[i].age,
    12. pc->data[i].sex,
    13. pc->data[i].tele,
    14. pc->data[i].addr);
    15. printf("\n");
    16. printf("-----------------------------------------------------------------------------\n");
    17. }
    18. }

    6.当查找、删除、更改时都需要进行查找,所以直接封装一个查找函数(找到了返回下标)

    1. //查找联系人
    2. static int Findcontact(Contact* pc, char* name) {
    3. assert(pc);
    4. for (int i = 0; i < pc->count; i++) {
    5. if (strcmp(name, pc->data[i].name) == 0) {
    6. return i;
    7. }
    8. }
    9. return -1;
    10. }

    7.查找联系人

    1. void Searchcontact(Contact* pc) {
    2. assert(pc);
    3. char name[20] = { 0 };
    4. printf("请输入要查找的联系人名字:>");
    5. scanf("%s", name);
    6. //查找
    7. int pos = Findcontact(pc, name);
    8. //删除
    9. if (pos == -1) {
    10. printf("没有该联系人\n");
    11. return;
    12. }
    13. else {
    14. printf("找到了\n");
    15. printf("%-20s\t%-3s\t%-10s\t%-12s\t%-30s\n", "名字", "年龄", "性别", "电话", "地址");
    16. printf("-----------------------------------------------------------------------------\n");
    17. printf("%-20s\t%-5d\t%-10s\t%-12s\t%-30s", pc->data[pos].name,
    18. pc->data[pos].age,
    19. pc->data[pos].sex,
    20. pc->data[pos].tele,
    21. pc->data[pos].addr);
    22. printf("\n");
    23. printf("-----------------------------------------------------------------------------\n");
    24. }
    25. }

     8.删除联系人,删除后,由于是顺序表存储,将后面的数据向前一个结点覆盖,且count--

    1. void Delcontact(Contact* pc) {
    2. assert(pc);
    3. char name[20] = { 0 };
    4. printf("请输入要删除的联系人名字:>");
    5. scanf("%s", name);
    6. //查找
    7. int pos = Findcontact(pc, name);
    8. //删除
    9. if (pos == -1) {
    10. printf("没有该联系人\n");
    11. return;
    12. }
    13. for (int i = pos; i < pc->count + 1; i++) {//count+1防止溢出
    14. pc->data[i] = pc->data[i + 1];
    15. }
    16. pc->count--;
    17. printf("删除成功\n");
    18. }

    9.修改联系人,将信息覆盖即可:

    1. void Modifycontact(Contact* pc) {
    2. assert(pc);
    3. char name[20] = { 0 };
    4. printf("请输入要修改的联系人的名字:>");
    5. scanf("%s", name);
    6. //查找
    7. int pos = Findcontact(pc, name);
    8. //删除
    9. if (pos == -1) {
    10. printf("没有该联系人\n");
    11. return;
    12. }else {
    13. printf("修改后联系人名字:>");
    14. scanf("%s", pc->data[pos].name);
    15. printf("修改后联系人年龄:>");
    16. scanf("%d", &(pc->data[pos].age));
    17. printf("修改后联系人性别:>");
    18. scanf("%s", pc->data[pos].sex);
    19. printf("修改后联系人电话:>");
    20. scanf("%s", pc->data[pos].tele);
    21. printf("修改后联系人地址:>");
    22. scanf("%s", pc->data[pos].addr);
    23. printf("\n");
    24. printf("修改成功\n");
    25. }
    26. }

    10.排序,分为年龄和姓名,都用库函数qsort(默认升序)实现,年龄进行时稍微复杂,细节如下:

    1. //按姓名排序函数
    2. int Sort_by_name(const void* e1, const void* e2) {
    3. return strcmp(((PenInfo*)e1)->name, ((PenInfo*)e2)->name);
    4. }
    5. //按年龄排序
    6. int Sort_by_age(const void* e1, const void* e2) {
    7. if (((PenInfo*)e1)->age < ((PenInfo*)e2)->age) {
    8. return -1;
    9. }
    10. if (((PenInfo*)e1)->age > ((PenInfo*)e2)->age) {
    11. return 1;
    12. }
    13. if (((PenInfo*)e1)->age == ((PenInfo*)e2)->age) {
    14. return 0;
    15. }
    16. }
    17. void Sortcontact(Contact* pc) {
    18. assert(pc);
    19. int chiose;
    20. printf("(1.按姓名排序 2.按年龄排序):>");
    21. scanf("%d", &chiose);
    22. if (chiose == 1) {
    23. qsort(pc->data,pc->count,sizeof(PenInfo), Sort_by_name);
    24. printf("排序成功\n");
    25. }
    26. else if (chiose == 2) {
    27. qsort(pc->data, pc->count, sizeof(PenInfo), Sort_by_age);
    28. printf("排序成功\n");
    29. }
    30. else {
    31. printf("无效输入\n");
    32. return;
    33. }
    34. }

    11.保存联系人到相对路径“contact.txt”中,通过二进制进行输入输出,退出时保存,打开时读取。

    1. void SaveContact(Contact* pc) {
    2. FILE* pfWrite = fopen("contact.txt", "wb");
    3. if (pfWrite == NULL) {
    4. perror("SaveContact");
    5. return;
    6. }
    7. //用二进制的形式写入文件
    8. for (int i = 0; i <= pc->count; i++) {
    9. fwrite(pc->data+i, sizeof(PenInfo), 1, pfWrite);
    10. }
    11. //关闭文件
    12. fclose(pfWrite);
    13. pfWrite = NULL;
    14. }
    15. void LoadContact(Contact* pc) {
    16. assert(pc);
    17. FILE* pfRead = fopen("contact.txt", "rb");
    18. if (pfRead == NULL) {
    19. //perror("LoadContact");
    20. return;
    21. }
    22. while (fread(&(pc->data[pc->count]), sizeof(PenInfo), 1, pfRead) == 1) {
    23. //判断是否空间不足
    24. AddCapacity(pc);
    25. pc->count++;
    26. }
    27. fclose(pfRead);
    28. pfRead = NULL;
    29. }

    12.测试代码:

    1. #define _CRT_SECURE_NO_WARNINGS
    2. #include "contact.h"
    3. //创建菜单
    4. void menu() {
    5. printf("------------My ContactBook------------\n");
    6. printf("-----------1.Add linkman ------------\n");
    7. printf("-----------2.Del linkman ------------\n");
    8. printf("-----------3.Show linkman ------------\n");
    9. printf("-----------4.Search linkman ----------\n");
    10. printf("-----------5.Modify linkman ----------\n");
    11. printf("-----------6.Sort linkman -----------\n");
    12. printf("-----------0.Exit menu -------------\n");
    13. }
    14. int main() {
    15. int input = 0;
    16. //创建联系人
    17. Contact con;
    18. //初始化通讯录
    19. Initcontact(&con);
    20. do {
    21. menu();
    22. printf("请选择对应功能的编号:>");
    23. scanf("%d", &input);
    24. switch (input) {
    25. case 1:
    26. Addcontact(&con);
    27. break;
    28. case 2:
    29. Delcontact(&con);
    30. break;
    31. case 3:
    32. Showcontact(&con);
    33. break;
    34. case 4:
    35. Searchcontact(&con);
    36. break;
    37. case 5:
    38. Modifycontact(&con);
    39. break;
    40. case 6:
    41. Sortcontact(&con);
    42. break;
    43. case 0:
    44. SaveContact(&con);
    45. DestoryContact(&con);
    46. printf("退出通讯录\n");
    47. break;
    48. default :
    49. printf("选择错误\n");
    50. break;
    51. }
    52. } while (input);
    53. return 0;
    54. }

    测试结果:

  • 相关阅读:
    【JavaWeb】手把手教你Eclipse、IDEA集成Tomcat构建Web应用
    热分析技术在工业设备状态监测中的应用
    正则表达式
    32单片机基础:TIM输出比较
    Cento7 Docker安装Zabbix,定制自定义模板
    大工22春《施工组织课程设计》离线作业模板及要求【标准答案】
    使用 Mermaid 创建流程图,序列图,甘特图
    优化软件系统,解决死锁问题,提升稳定性与性能 redis排队下单
    金仓数据库KStudio使用手册(6. PLSQL调试)
    Golang net/http 标准库源码学习
  • 原文地址:https://blog.csdn.net/qq_43112916/article/details/133815868