C语言期末课程设计—【通讯录管理系统】让课程设计不再是痛苦2

简介: C语言期末课程设计—【通讯录管理系统】让课程设计不再是痛苦2

第三章 系统测试

3.1 菜单

3.2 增加联系人信息

3.3 删除联系人信息


3.4 查找联系人信息

3.5 修改联系人信息

3.6 按联系人信息排序

3.7 打印联系人信息

4.心得体会

在实现通讯录管理系统的过程中,我学到了很多关于C语言编程的技巧和经验。以下是我的心得体会

1. 数据结构的选择很重要。在通讯录管理系统中,我使用了结构体来存储联系人的信息,这样可以方便地对联系人进行增删改查操作。


2. 内存管理要注意。在使用动态内存分配函数(如malloc和free)时,要注意及时释放内存,避免内存泄漏。


3. 错误处理很重要。在编写程序时,要考虑到各种可能出现的错误情况,并对其进行处理,以保证程序的稳定性和可靠性。


4. 模块化编程可以提高代码的可读性和可维护性。在编写通讯录管理系统时,我将不同功能的代码分成了多个模块,这样可以方便地对代码进行修改和维护。


5. 调试是编程过程中必不可少的一步。在编写通讯录管理系统时,我经常使用调试工具来查找程序中的错误,以便及时进行修复。


总之,通过实现通讯录管理系统,我不仅学到了很多关于C语言编程的技巧和经验,还提高了自己的编程能力和解决问题的能力。


5. 源码

5.1 DynamicContact.h

通讯录函数声明部分

#pragma once
#define _CRT_SECURE_NO_WARNINGS //vs 编译器需要,其他编译器不需要,可自行删去
//动态版通讯录
#include <stdio.h>
#include <assert.h>
#include <string.h>
#include <stdlib.h>
#include <Windows.h>
//类型声明
//PeoInit结构体所用
#define NAME_MAX 20
#define SEX_MAX 5
#define TELE_MAX 12
#define ADDR_MAX 30
//通讯录初始状态的容量大小
#define DEFAULT_SZ 3
//枚举选项
enum Option //test函数所用的枚举
{
  EXIT,
  ADD,
  DEL,
  SEARCH,
  MODIFY,
  SORT,
  PRINT
};
enum Modify //修改联系人所用的枚举
{
  EXIT0,
  NAME,
  SEX,
  AGE,
  TELE,
  ADDR
};
//结构体声明
typedef struct PeoInfo
{
  char name[NAME_MAX];
  char sex[SEX_MAX];
  int age;
  char tele[TELE_MAX];
  char addr[ADDR_MAX];
}PeoInfo;
typedef struct Contact
{
  PeoInfo* data;//存放联系人的信息
  int count;//通讯录中已经保存的信息个数
  int capacity;//记录通讯录当前的最大容量
}Contact;
//函数声明
//初始化通讯录
void InitContact(Contact* p);
//销毁通讯录
void DestroyContact(Contact* p);
//添加联系人
void AddContact(Contact* p);
//删除联系人
void DelContact(Contact* p);
//查找联系人
void SearchContact(const Contact* p);
//修改联系人信息
void ModifyContact(Contact* p);
//打印联系人
void PrintContact(const Contact* p);
//排序
void SortContact(const Contact* p);
//保存通讯录的信息到文件
void SaveContact(const Contact* pc);
//加载文件信息到通讯录中
void LoadContact(Contact* p);


5.2 DynamicContact.c

通讯录功能实现部分

1. #include#include "DynamicContact.h"
//排序所用菜单
void menu2()
{
  printf("********************************\n");
  printf("******  1.name    2.age   ******\n");
  printf("******  0.exit            ******\n");
  printf("********************************\n");
}
//修改联系人所用的菜单
void menu1()
{
  printf("********************************\n");
  printf("******  1.name    2.sex   ******\n");
  printf("******  3.age     4.tele  ******\n");
  printf("******  5.addr    0.exit  ******\n");
  printf("********************************\n");
}
//检测通讯录容量
void CheckCapacity(Contact* p)
{
  assert(p);
  if (p->capacity == p->count)
  {
    PeoInfo* tmp = (PeoInfo*)realloc(p->data, (p->capacity + 2) * sizeof(PeoInfo));
    if (p->data != NULL)
    {
      p->data = tmp;
    }
    else
    {
      perror("CheckCapacity::realloc");
      return;
    }
    p->capacity += 2;
    printf("增容成功\n");
  }
}
//初始化通讯录
void InitContact(Contact* p)
{
  assert(p);
  p->count = 0;
  p->capacity = DEFAULT_SZ;
  p->data = (PeoInfo*)malloc(p->capacity * sizeof(PeoInfo));
  if (p->data == NULL)
  {
    perror("InitContact::malloc");
    return;
  }
  memset(p->data, 0, p->capacity * sizeof(PeoInfo));//把PeoInit全部初始化为0
  //加载文件信息到通讯录中
  LoadContact(p);
}
//销毁通讯录
void DestroyContact(Contact* p)
{
  free(p->data);
  p->data = NULL;
  p->capacity = 0;
  p->count = 0;
  printf("销毁成功\n");
}
//添加联系人
void AddContact(Contact* p)
{
  //检查容量
  CheckCapacity(p);
  //录入信息
  printf("请输入名字:>");
  scanf("%s", p->data[p->count].name);
  printf("请输入性别:>");
  scanf("%s", p->data[p->count].sex);
  printf("请输入年龄:>");
  scanf("%d", &(p->data[p->count].age));
  printf("请输入电话:>");
  scanf("%s", p->data[p->count].tele);
  printf("请输入地址:>");
  scanf("%s", p->data[p->count].addr);
  p->count++;
  printf("添加成功\n\n");
}
//查找,找到了返回下标,找不到返回 -1
int FindName(const Contact* p, char name[])
{
  assert(p);
  int i = 0;
  for (i = 0; i < p->count; i++)
  {
    if (0 == strcmp(p->data[i].name, name))
    {
      return i;
    }
  }
  return -1;
}
//删除联系人
void DelContact(Contact* p)
{
  assert(p);
  if (0 == p->count)
  {
    printf("通讯录已空,无法删除\n");
    return;
  }
  char name[NAME_MAX];
  printf("请输入要查找的名字:>");
  scanf("%s", name);
  int position = FindName(p, name);//查找
  if (-1 == position)
  {
    printf("要删除的联系人不存在\n\n");
    return;
  }
  //删除
  int i = 0;
  for (i = position; i < p->count - 1; i++)
  {
    p->data[i] = p->data[i + 1];
  }
  p->count--;
  printf("删除成功\n\n");
}
//查找联系人
void SearchContact(const Contact* p)
{
  assert(p);
  char name[NAME_MAX];
  printf("请输入要查找的名字:>");
  scanf("%s", name);
  int position = FindName(p, name);//查找
  if (-1 == position)
  {
    printf("要查找的联系人不存在\n\n");
    return;
  }
  printf("\n-----------------------------------------------\n");
  printf("%-10s %-5s %-5s %-12s %-30s\n", "姓名", "性别", "年龄", "电话", "地址");
  printf("%-10s %-5s %-5d %-12s %-30s\n", p->data[position].name,
    p->data[position].sex, p->data[position].age,
    p->data[position].tele, p->data[position].addr);
  printf("\n-----------------------------------------------\n\n");
}
//修改联系人信息
void ModifyContact(Contact* p)
{
  assert(p);
  int intput = 0;
  char name[NAME_MAX];
  printf("请输入要修改联系人的名字:>");
  scanf("%s", name);
  int position = FindName(p, name);//查找
  if (-1 != position)
  {
    printf("\n-----------------------------------------------\n");
    printf("%-10s %-5s %-5s %-12s %-30s\n", "姓名", "性别", "年龄", "电话", "地址");
    printf("%-10s %-5s %-5d %-12s %-30s\n", p->data[position].name, p->data[position].sex,
      p->data[position].age, p->data[position].tele, p->data[position].addr);
    printf("\n-----------------------------------------------\n\n");
    do
    {
      menu1();
      printf("请输入要修改的选项:>");
      scanf("%d", &intput);
      switch (intput)
      {
      case NAME:
        printf("请修改名字:>");
        scanf("%s", p->data[position].name);
        printf("修改成功\n\n");
        break;
      case SEX:
        printf("请修改性别:>");
        scanf("%s", p->data[position].sex);
        printf("修改成功\n\n");
        break;
      case AGE:
        printf("请修改年龄:>");
        scanf("%d", &(p->data[position].age));
        printf("修改成功\n\n");
        break;
      case TELE:
        printf("请修改电话号码:>");
        scanf("%s", p->data[position].tele);
        printf("修改成功\n\n");
        break;
      case ADDR:
        printf("请修改地址:>");
        scanf("%s", p->data[position].addr);
        printf("修改成功\n\n");
        break;
      case EXIT0:
        printf("退出修改\n\n");
        break;
      default:
        printf("选择错误,请重新选择\n\n");
        break;
      }
    } while (intput);
  }
  else
  {
    printf("所要修改的联系人不存在\n\n");
    return;
  }
}
//打印联系人
void PrintContact(const Contact* p)
{
  assert(p);
  int i = 0;
  printf("\n-----------------------------------------------\n");
  printf("%-10s %-5s %-5s %-12s %-30s\n", "姓名", "性别", "年龄", "电话", "地址");
  for (i = 0; i < p->count; i++)
  {
    printf("%-10s %-5s %-5d %-12s %-30s\n", p->data[i].name, p->data[i].sex,
      p->data[i].age, p->data[i].tele, p->data[i].addr);
  }
  printf("-----------------------------------------------\n\n");
}
int cmp_name(const void* e1, const void* e2)
{
  return strcmp(((struct PeoInfo*)e1)->name, ((struct PeoInfo*)e2)->name);
}
int cmp_age(const void* e1, const void* e2)
{
  return (((struct PeoInfo*)e1)->age - ((struct PeoInfo*)e2)->age);
}
//排序
void SortContact(const Contact* p)
{
  assert(p);
  int intput = 0;
  do
  {
    menu2();
    printf("请选择需要排序的选项:>");
    scanf("%d", &intput);
    switch (intput)
    {
    case 1:
      qsort(p->data, p->count, sizeof(struct PeoInfo), cmp_name);
      printf("按名字排序成功\n\n");
      break;
    case 2:
      qsort(p->data, p->count, sizeof(struct PeoInfo), cmp_age);
      printf("按年龄排序成功\n\n");
      break;
    case 0:
      printf("退出排序\n\n");
      break;
    default:
      printf("选择错误,请重新选择\n\n");
      break;
    }
  } while (intput);
}
//保存通讯录的信息到文件
void SaveContact(const Contact* p)
{
  //打开并创建文件
  FILE* pf = fopen("contact.data.txt", "w");//w:只写,
  if (pf == NULL)
  {
    perror("SaveContact::fopen");
    return;
  }
  //写文件
  int i = 0;
  for (i = 0; i < p->count; i++)
  {
    fwrite(p->data + i, sizeof(PeoInfo), 1, pf);
  }
  //关闭文件
  fclose(pf);
  pf = NULL;
}
//加载文件信息到通讯录中
void LoadContact(Contact* p)
{
  //打开文件
  FILE* pf = fopen("contact.data.txt", "r");//r:只读
  if (pf == NULL)
  {
    perror("LoadContact::fopen");
    return;
  }
  //读文件
  PeoInfo tmp = { 0 };
  while (fread(&tmp, sizeof(PeoInfo), 1, pf))
  {
    CheckCapacity(p);
    p->data[p->count] = tmp;
    p->count++;
  }
  //关闭文件
  fclose(pf);
  pf = NULL;
}


5.3 test.c

通讯录系统设计测试部分

#include "DynamicContact.h"
void menu()
{
  printf("================================\n");
  printf("*********** Contact ************\n");
  printf("================================\n");
  printf("***     1.add     2.del      ***\n");
  printf("***     3.search  4.modify   ***\n");
  printf("***     5.sort    6.print    ***\n");
  printf("***     0.exit               ***\n");
  printf("================================\n");
}
void test()
{
  int intput = 0;
  Contact con;//创建通讯录
  InitContact(&con);//初始化通讯录
  do
  {
    menu();
    printf("请选择:>");
    scanf("%d", &intput);
    switch (intput)
    {
    case ADD:
      AddContact(&con);
      break;
    case DEL:
      DelContact(&con);
      break;
    case SEARCH:
      SearchContact(&con);
      break;
    case MODIFY:
      ModifyContact(&con);
      break;
    case SORT:
      SortContact(&con);
      break;
    case PRINT:
      PrintContact(&con);
      break;
    case EXIT:
      SaveContact(&con);//销毁通讯录之前把数据存入文件中
      DestroyContact(&con);
      printf("退出通讯录\n");
      break;
    default:
      printf("输入错误,请重新输入\n\n");
      break;
    }
  } while (intput);
}
int main()
{
  test();
  return 0;
}


本篇博客借鉴于博主枫叶先生,如果大家想学习本篇中的流程图画图方法和工具获取,可以前去关注这个博主!!!

如果觉得文章不错,期待你的一键三连哦,你个鼓励是我创作的动力之源,让我们一起加油,顶峰相见!!!

相关文章
|
1月前
|
程序员 C语言 开发者
pymalloc 和系统的 malloc 有什么区别
pymalloc 和系统的 malloc 有什么区别
|
5天前
|
IDE 编译器 开发工具
【C语言】全面系统讲解 `#pragma` 指令:从基本用法到高级应用
在本文中,我们系统地讲解了常见的 `#pragma` 指令,包括其基本用法、编译器支持情况、示例代码以及与传统方法的对比。`#pragma` 指令是一个强大的工具,可以帮助开发者精细控制编译器的行为,优化代码性能,避免错误,并确保跨平台兼容性。然而,使用这些指令时需要特别注意编译器的支持情况,因为并非所有的 `#pragma` 指令都能在所有编译器中得到支持。
71 41
【C语言】全面系统讲解 `#pragma` 指令:从基本用法到高级应用
|
1月前
|
程序员 C语言 开发者
pymalloc 和系统的 malloc 有什么区别?
pymalloc 和系统的 malloc 有什么区别?
|
2月前
|
C语言
大学生期末C语言实验(学生成绩和鞍点)
大学生期末C语言实验(学生成绩和鞍点)
205 0
大学生期末C语言实验(学生成绩和鞍点)
|
2月前
|
存储 C语言
探索C语言数据结构:利用顺序表完成通讯录的实现
本文介绍了如何使用C语言中的顺序表数据结构实现一个简单的通讯录,包括初始化、添加、删除、查找和保存联系人信息的操作,以及自定义结构体用于存储联系人详细信息。
32 2
|
2月前
|
存储 编译器 C语言
【C语言】学生管理系统:完整模拟与实现(一)
【C语言】学生管理系统:完整模拟与实现
|
2月前
|
存储 C语言
手把手教你用C语言实现通讯录管理系统
手把手教你用C语言实现通讯录管理系统
|
2月前
|
测试技术 C语言
【C语言】学生管理系统:完整模拟与实现(三)
【C语言】学生管理系统:完整模拟与实现
|
2月前
|
C语言
【C语言】学生管理系统:完整模拟与实现(二)
【C语言】学生管理系统:完整模拟与实现
|
4月前
|
存储 C语言
学生管理系统(C语言简单实现)
这篇文章是关于使用C语言实现一个简单的学生管理系统,包括文件的基本应用、数据结构设计、函数实现以及用户界面交互。
学生管理系统(C语言简单实现)