文章目录

  • 通讯录实现
  • 一、实现目的和意义
  • 二、实现内容
  • 三、实现功能
  • 四、实现逻辑
    • (一)、menu菜单函数
    • (二)、创建结构体并初始化
    • (三)、在do..while循环里面用switch创建功能函数和退出功能
      • (1)、创建增加函数
      • (2)、创建删除函数
      • (3)、创建搜索函数
      • (4)、创建修改函数
      • (5)、创建展示函数
      • (6)、创建排序函数
      • (7)、创建退出功能
  • 五、实现结果
  • 六、实现源代码
    • (1)Phone.h
    • (2)text.c
    • (3)Phone.c

通讯录实现

一、实现目的和意义

  • 1、提高解决实际问题的能力和动手能力
  • 2、巩固和加深对c怨言的理解
  • 3、练习编译器的调试

二、实现内容

用C语言去实现可以存放1000人的通讯录。

三、实现功能

实现的通讯录可以实现增加、删除、搜索、修改、展示信息内容、对电话信息进行按名字或年龄排序。

四、实现逻辑

(一)、menu菜单函数

void menu()//功能列表{printf("***************************************\n");printf("*******    1、add       2、del    *******\n");printf("*******    3、search    4、modify *******\n");printf("*******    5、show      6、sort   *******\n");printf("*******         0、exit           *******\n");printf("***************************************\n");}

(二)、创建结构体并初始化

  • 创建结构体:
#define MAX 1000#define MAX_name 20#define MAX_sex 5#define MAX_tel 13#define MAX_addr 30struct P{char name[MAX_name];char sex[MAX_sex];int age;char tel[MAX_tel];char adress[MAX_addr];};struct Phone{struct P data[MAX];int sz;};

创建两个结构体,一个是存放一个人的信息,另一个是存放数组和当前人数量。人信息用宏来代替便于修改。

  • 初始化通讯录:
void InitPhone(struct Phone* pc){assert(pc);memset(pc->data, 0, MAX*sizeof(struct P));pc->sz = 0;}

初始化时,传的是结构体Phone的地址,用结构体指针pc来接收,里面并用aasert断言一下,一以便直到是哪行出了问题,再用memset函数,把结构体P里面的信息置为0,及把sz记录当前数量置为0。

(三)、在do…while循环里面用switch创建功能函数和退出功能

(1)、创建增加函数

void AddPhone(struct Phone* pc){assert(pc);//日常断言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].tel);printf("输入地址:");scanf("%s", pc->data[pc->sz].adress);pc->sz++;printf("成功添加\n");}

函数解析:

  • 用结构体指针变量pc接收,直接用5个打印函数,去录入信息,如名字,用pc找到数组,并用pc找到sz作为下标,再.name找到名字。
  • 里面要注意再用scanf的时候数组是数组名地址,不用加&,而整型变量要加取地址符号。
  • 最后用pc找到sz++,记录已录人数,并打印成功添加。

(2)、创建删除函数

void  DelPhone(struct Phone* pc){char name[MAX_name];printf("输入删除的名字:");scanf("%s", name);int ret = Find_name(pc, name);if (ret == -1){printf("删除的人不存在");}else{for (int j = ret; j < pc->sz; j++){pc->data[j] = pc->data[j + 1];}pc->sz--;printf("已删除改联系人\n");}}

函数解析:

  • 在里面要先创建name数组,来存放要删除的名字,之后需要判断要删除的人是否存在还需创建Find_name()函数来判断,并用ret接收。此函数如下:
int Find_name(struct Phone* pc, char name[]){for (int i = 0; i < pc->sz; i++){if (strcmp(pc->data[i].name, name) == 0){return i;}}return -1;}

函数解析:
** 除了用pc接收,还要接收删除name的地址,在里面用for循环,遍历查找,里面再用if判断语句来判断,用strcmp比较函数来比较所输入名字和通讯录名字是否一样。
** 如果一样返回下标。没有找到返回-1。

  • 找到之后用for循环把后面的元素左移。
  • 最后人数减一。

(3)、创建搜索函数

void SearchPhone(struct Phone* pc){char name[MAX_name];printf("输入搜索的名字:");scanf("%s", name);int ret = Find_name(pc, name);if (ret == -1){printf("搜索的人不存在");}else{printf("%-20s\t%-5s\t%-10s\t%-13s\t%-30s\n", "姓名", "性别", "年龄", "电话号码", "地址");printf("%-20s\t%-5s\t%-10d\t%-13s\t%-30s\n", pc->data[ret].name, pc->data[ret].sex,pc->data[ret].age, pc->data[ret].tel, pc->data[ret].adress);}}

函数解析:

  • 前面的步骤和删除步骤一样,需要判断搜索的人是否存在,如果存在打印。
  • 为了让信息显示的更美观和直观,用对齐方式来实现且上下两个打印函数保持一致,负号表示右对齐。

(4)、创建修改函数

void ModifyPhone(struct Phone* pc){char name[MAX_name];printf("输入修改的名字:");scanf("%s", name);int ret = Find_name(pc, name);if (ret == -1){printf("修改的人不存在");}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].tel);printf("输入地址:");scanf("%s", pc->data[ret].adress);printf("已修改改联系人\n");}}

函数解析:

  • 和前面一样需要判断修改的人是否存在,存在返回下标,在此下标直接覆盖。
  • 最后打印修改联系人。

(5)、创建展示函数

void ShowPhone(struct Phone* pc){printf("%-20s\t%-5s\t%-10s\t%-13s\t%-30s\n", "姓名","性别","年龄","电话号码","地址");for (int i = 0; i < pc->sz; i++){printf("%-20s\t%-5s\t%-10d\t%-13s\t%-30s\n", pc->data[i].name, pc->data[i].sex,pc->data[i].age, pc->data[i].tel, pc->data[i].adress);}}

函数解析:

  • 还是要实现对齐保持上下一致,用for循环直接打印全部信息。

(6)、创建排序函数

int cmp_name(const void* e1,const void* e2){return strcmp(((struct P*)e1)->name ,((struct P*)e2)->name);}void SortPhone(struct Phone* pc){qsort(pc->data,pc->sz,sizeof(struct P),cmp_name);}

函数解析:

  • 创建排序函数时,要知道qsort函数的用法,qsort需要传4个参数。
    第一是数组地址,第二是数组个数,第三每个个数大小(单位字节),函数指针。
  • 函数指针,也即是函数名,需要调用的函数。
  • 在此这个被调用函数里面,需要用void*指针来接收,因为不知道传的是什么类型。
  • 在里面用strcmp比较名字大小或者年龄大小。
  • 在strcmp里面需把空指针转换为结构体指针,再用这个指针找到要比较的类型名。

(7)、创建退出功能

直接打印退出功能,退出循环。

五、实现结果



六、实现源代码

(1)Phone.h

#pragma once#include#include#include#include#define MAX 1000#define MAX_name 20#define MAX_sex 5#define MAX_tel 13#define MAX_addr 30struct P{char name[MAX_name];char sex[MAX_sex];int age;char tel[MAX_tel];char adress[MAX_addr];};struct Phone{struct P data[MAX];int sz;};void InitPhone(struct Phone* pc);void AddPhone(struct Phone* pc);void DelPhone(struct Phone* pc);void SearchPhone(struct Phone* pc);void ModifyPhone(struct Phone* pc);void ShowPhone(struct Phone* pc);void SortPhone(struct Phone* pc);int Find_name(struct Phone* pc, char name[]);int cmp_name(const void* e1, const void* e2);

(2)text.c

#include"phone.h"void menu(){printf("***************************************\n");printf("*******    1、add       2、del    *******\n");printf("*******    3、search    4、modify *******\n");printf("*******    5、show      6、sort   *******\n");printf("*******         0、exit           *******\n");printf("***************************************\n");}int main(){int input = 0;struct Phone con;InitPhone(&con);do{menu();printf("请选择->");scanf("%d", &input);switch (input){case 1:AddPhone(&con);break;case 2:DelPhone(&con);break;case 3:SearchPhone(&con);break;case 4:ModifyPhone(&con);break;case 5:ShowPhone(&con);break;case 6:SortPhone(&con);break;case 0:printf("退出通讯录\n");break;default:printf("选择错误\n");break;}} while (input);return 0;}

(3)Phone.c

#include"phone.h"void InitPhone(struct Phone* pc){assert(pc);memset(pc->data, 0, MAX*sizeof(struct P));pc->sz = 0;}void AddPhone(struct Phone* pc){assert(pc);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].tel);printf("输入地址:");scanf("%s", pc->data[pc->sz].adress);pc->sz++;printf("成功添加\n");}void ShowPhone(struct Phone* pc){printf("%-20s\t%-5s\t%-10s\t%-13s\t%-30s\n", "姓名","性别","年龄","电话号码","地址");for (int i = 0; i < pc->sz; i++){printf("%-20s\t%-5s\t%-10d\t%-13s\t%-30s\n", pc->data[i].name, pc->data[i].sex,pc->data[i].age, pc->data[i].tel, pc->data[i].adress);}}int Find_name(struct Phone* pc, char name[]){for (int i = 0; i < pc->sz; i++){if (strcmp(pc->data[i].name, name) == 0){return i;}}return -1;}void  DelPhone(struct Phone* pc){char name[MAX_name];printf("输入删除的名字:");scanf("%s", name);int ret = Find_name(pc, name);if (ret == -1){printf("删除的人不存在");}else{for (int j = ret; j < pc->sz; j++){pc->data[j] = pc->data[j + 1];}pc->sz--;printf("已删除改联系人\n");}}void ModifyPhone(struct Phone* pc){char name[MAX_name];printf("输入修改的名字:");scanf("%s", name);int ret = Find_name(pc, name);if (ret == -1){printf("修改的人不存在");}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].tel);printf("输入地址:");scanf("%s", pc->data[ret].adress);printf("已修改改联系人\n");}}int cmp_name(const void* e1,const void* e2){return strcmp(((struct P*)e1)->name ,((struct P*)e2)->name);}void SortPhone(struct Phone* pc){qsort(pc->data,pc->sz,sizeof(struct P),cmp_name);}void SearchPhone(struct Phone* pc){char name[MAX_name];printf("输入搜索的名字:");scanf("%s", name);int ret = Find_name(pc, name);if (ret == -1){printf("搜索的人不存在");}else{printf("%-20s\t%-5s\t%-10s\t%-13s\t%-30s\n", "姓名", "性别", "年龄", "电话号码", "地址");printf("%-20s\t%-5s\t%-10d\t%-13s\t%-30s\n", pc->data[ret].name, pc->data[ret].sex,pc->data[ret].age, pc->data[ret].tel, pc->data[ret].adress);}}