我们今天通过实现一个静态通讯录,来回顾一下结构体知识。涵盖的知识点有:

  • 建立结构声明
  • 定义结构变量
  • 初始化结构
  • 访问结构成员
  • 结构数组
  • 嵌套结构
  • 指向结构的指针
  • 利用指针访问结构
  • 传递结构
  • 枚举

为遵循模块化编程,我们将代码分为了3个部分:

  1. contact.h-----头文件, 用来放置函数声明包含头文件
  2. contact.c-----实现模块,用来实现通讯录的功能
  3. tect.c---------测试模块,用来测试功能是否正常运转

实现思想:

存放联系人信息------->建立结构数组

通讯录各种功能------->建立不同函数,实现模块化

代码实现:

contact.h-----头文件, 用来放置函数声明包含头文件

#pragma once

#define _CRT_SECURE_NO_WARNINGS 1

#define MAX_CON 100
#define MAX_NAME 20
#define MAX_TELEPHONE 12
#define MAX_SEX 10
#define MAX_ADDR 30

#include <stdio.h>
#include <assert.h>
#include <string.h>
#include <stdlib.h>

//选择菜单
void Menu();

enum Option
{
	EXIT,
	ADD,
	DEL,
	SEARCH,
	MODIFY,
	SHOW,
	SORT
};

//定义通讯录信息
typedef  struct PeoInfo
{
	char name[MAX_NAME];
	char telephone[MAX_TELEPHONE];
	char sex[MAX_SEX];
	char addr[MAX_ADDR];
	int age;
}PeoInfo;

//定义通讯录
typedef struct Contact
{
	PeoInfo data [MAX_CON];
	int count;
}Contact;

//初始化通讯录
void InitStruct(Contact* pc);

//显示整个通讯录
void Show(const Contact* pc);

//显示指定联系人
void ShowSolo(const Contact* p, int position);

//增加联系人
void Add(Contact* pc);

//删除联系人
void Del(Contact* pc);

//查找联系人
void Search(const Contact* pc);

//修改联系人信息
void Modify(Contact* pc);

//排序通讯录 -- 按名字排序
void Sort(Contact* pc);

contact.c-----实现模块,用来实现通讯录的功能

#include "contact.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");
}

//查找函数,返回值为下标
static int FindName(const Contact* pc, const char* name)
{
	assert(pc && name);

	int i = 0;

	for (i = 0; i < pc->count; i++)
	{
		if (0 == strcmp(pc->data[i].name, name))//找到联系人,返回下标
		{
			return i;
		}
	}
	return -1;//没有此联系人
}

void InitStruct(Contact* pc)
{
	assert(pc);

	pc->count = 0;
	memset(pc->data, 0, sizeof(pc->data));
}

void Show(const Contact* pc)
{
	assert(pc);

	printf("%-6s\t%-6s\t%-2s\t%-11s\t%-10s\n", "名字", 
												"性别", 
												"年龄", 
												"号码", 
												"地址");
	int i = 0;

	for (i = 0; i < pc->count; i++)
	{
		ShowSolo(pc, i);
	}
}

void ShowSolo(const Contact* pc, int position)
{
	assert(pc);

	printf("%-6s\t%-6s\t%-2d\t%-11s\t%-10s\n", pc->data[position].name,
												pc->data[position].sex,
												pc->data[position].age,
												pc->data[position].telephone,
												pc->data[position].addr);
}

void Add(Contact* pc)
{
	assert(pc);

	if (MAX_CON == pc->count)
	{
		printf("通讯录已满,无法进行添加\n");
		return;
	}

	printf("请输入名字:");
	scanf("%s", pc->data[pc->count].name);
	printf("请输入年龄:");
	scanf("%d", &pc->data[pc->count].age);
	printf("请输入性别:");
	scanf("%s", pc->data[pc->count].sex);
	printf("请输入号码:");
	scanf("%s",pc->data[pc->count].telephone);
	printf("请输入地址:");
	scanf("%s", pc->data[pc->count].addr);

	pc->count++;
}

void Del(Contact* pc)
{
	assert(pc);

	//判断是否有元素可供删除
	if (0 == pc->count)
	{
		printf("通讯录为空,请添加联系人后再进行删除\n");
		return;
	}

	int i = 0;
	int position = 0;
	char tem_name[MAX_NAME] = { 0 };
	int n = 0;
	
	printf("请输入您要删除的联系人名字:");
	scanf("%s", tem_name);

	position = FindName(pc, tem_name);

	//没有此联系人
	if (-1 == position)
	{
		printf("没有此联系人\n");
		return;
	}

	//进行删除操作
	for (i = position; i < pc->count - 1; i++)
	{
		pc->data[i] = pc->data[i + 1];
	}

	pc->count--;
	
	printf("已删除联系人%s\n", tem_name);

}

void Search(const Contact* pc)
{
	assert(pc);

	char name[MAX_NAME];
	int position = 0;

	printf("请输入要查找的联系人名字:");
	scanf("%s", name);

	position = FindName(pc, name);

	if (-1 == position)
	{
		printf("该用户不存在\n");
		return;
	}

	printf("查找成功\n");

	printf("%-6s\t%-6s\t%-2s\t%-11s\t%-10s\n", "名字",
												"性别",
												"年龄",
												"号码",
												"地址");
	ShowSolo(pc, position);
}

void Modify(Contact* pc)
{
	assert(pc);

	char name[MAX_NAME];
	int position = 0;
	PeoInfo tem = { 0 };

	printf("请输入要修改的联系人名字:");
	scanf("%s", name);

	position = FindName(pc, name);

	if (-1 == position)
	{
		printf("该联系人不存在\n");
		return;
	}
	
	printf("请输入修改后的信息\n");

	printf("请输入名字:");
	scanf("%s", pc->data[position].name);
	printf("请输入年龄:");
	scanf("%d", &pc->data[position].age);
	printf("请输入性别:");
	scanf("%s", pc->data[position].sex);
	printf("请输入号码:");
	scanf("%s", pc->data[position].telephone);
	printf("请输入地址:");
	scanf("%s", pc->data[position].addr);

	printf("修改成功\n");
}

static int Compare(const void* p1, const void* p2)
{
	assert(p1 && p2);

	return strcmp(((PeoInfo*)p1)->name, ((PeoInfo*)p2));
}

void Sort(Contact* pc)
{
	qsort(pc->data, pc->count, sizeof(PeoInfo), Compare);

	printf("排序成功\n");
}

tect.c---------测试模块,用来测试功能是否正常运转

#include "contact.h"

int main()
{
	int input = 0;
	Contact con;

	InitStruct(&con);

	do {
		Menu();

		printf("请问您需要进行什么操作:\n");
		scanf("%d", &input);
		switch (input)
		{
		case ADD:
			Add(&con);
			break;
		case DEL:
			Del(&con);
			break;
		case SEARCH:
			Search(&con);
			break;
		case MODIFY:
			Modify(&con);
			break;
		case SHOW:
			Show(&con);
			break;
		case SORT:
			Sort(&con);
			break;
		case EXIT:
			printf("已退出,欢迎下次使用\n");
			break;
		default :
			printf("输入错误,请重新选择:\n");
			break;
		}
	} while (input);

	return 0;
}