通讯录(普通版)

目录

前言:

1. 联系人信息的存放以及一些提前预备

2. 目录(text.c的构建)

3. 增加联系人信息

4. 删除用户的信息

5. 查找联系人

6. 修改联系人

7. 联系人排序

8. 打印用户的信息

9. 总代码

        text.c

        contact.h

        contact.c


前言:

    我们需要对此功能进行构思:

        首先本人将通讯录功能提供为:

0. exit 退出
1. add

增加联系人

2. del

删除联系人

3. search

查找联系人

4. modify

修改联系人

5. sort

联系人排序

6. print

打印联系人

        其次本人将通讯录以多文件实现:

接口的实现 contact.c
接口的声明 contact.h
测试通讯录的功能 text.c

1. 联系人信息的存放以及一些提前预备

        以text.ccontact.c所都需要的内容为主要,我们以放入头文件contact.h中进行编写,例如:头文件,结构体的编写等,这样可以极大的提高代码的清晰性,更加便于阅读。无需将同样的内容在不同文件中反复书写。

        代码涉及的一些小技巧:

  1.         我利用define定义常量的方式,提高代码的更改性,毕竟特殊的名字,地址等,都很有可能会突破所定的大小,如果更改会很麻烦,但是用define定义常量的方式就会很简单了,只用更改此处一次即可。尤其是对于联系人的数目的问题。
  2.         我以typedef进行类型重命名结构体,必进以此种方式可以使得后期对类型的使用无需struct Information之类的长句子,只需要以Information。这可以将后续代码的编写变得更加轻松。
#define MAX 1000 //联系人的存储上限

#define NAME_MAX 20 //名字的存储上限
#define SEX_MAX 3 //性别的存储上限
#define TELT_MAX 12 //电话的存储上限
#define ADDR_AMX 20 //地址的存储上限

typedef struct Infotmation
{
	char name[NAME_MAX]; //名字
	char sex[SEX_MAX]; //性别
	int age; //年龄
	char tele[TELT_MAX]; //电话
	char addr[ADDR_AMX]; //住址
}Infotmation;

        代码涉及的一些小技巧:

  1.          对于联系人的存储,我们应该知道存储了多少位,于是我们应该初始化一个sz变量,计算我们存储联系人的个数。但是我们会发现一个问题,由于重要的变量是两个,是每次函数传参所必须的内容,所以,我们可以利用结构体的“高内聚,低耦合”的特点,将其结合为一个结构体,这样后续的运用,只需运用结构体的方法即可,这样更加便利。
typedef struct Contact
{
	Infotmation date[MAX];
	int sz;
}Contact;

2. 目录(text.c的构建)

enum Option
{
	EXIT,
	ADD,
	DEL,
	SEARCH,
	MODIFY,
	SORT,
	PRINT
};
#define _CRT_SECURE_NO_WARNINGS 1

#include "contact.h"

void menu()
{
	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");
	printf("******请选择所需功能*******\n");
}

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

	//数据初始化
	InitContact(&Con);

	do
	{
		menu();
		scanf("%d", &input);
		switch (input)
		{
		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: //退出
			break;
		default:
			printf("输入错误,请重新输入\n");
			break;
		}
	} while (input);
	return 0;
}

        代码涉及的一些小技巧:

  1.         可以很明显的发现,我在case后写的不是数字,而是字符,但其实这本质就是数字,我已用枚举的方式将其,定义为枚举常量,这就用到枚举的优点:(1)增加代码的可读性和可维护性(2)便于调试。        

        我们需要注意一个问题,我们在前面对用户数组的创建与sz的中,并未对其经进行初始化,这意味着里面就是随机值,这样是不行的,于是我们需要对其进行初始化。

//数据初始化
void InitContact(Contact* pc)
{
	assert(pc);
	pc->sz = 0;
	memset(pc->date, 0, sizeof(pc->date));
}

3. 增加联系人信息

//增加联系人信息
void AddContact(Contact* pc)
{
	assert(pc);
	
    printf("请输入名字:\n");
	scanf("%s", pc->date[pc->sz].name);
	printf("请输入性别:\n");
	scanf("%s", pc->date[pc->sz].sex);
	printf("请输入年龄:\n");
	scanf("%d", &(pc->date[pc->sz].age));
	printf("请输入电话:\n");
	scanf("%s", pc->date[pc->sz].tele);
	printf("请输入地址:\n");
	scanf("%s", pc->date[pc->sz].addr);

	pc->sz++;
	printf("输入成功\n");
}

        需要注意的一点 ,之前对年龄的定义是int类型的,于是在scanf函数中,我们需要注意指向到age后,对整体一定要有一个取地址(&)。

4. 删除用户的信息

//删除用户的信息
void DelContact(Contact* pc)
{
	assert(pc);
	//查找
	char arr[20] = { 0 };
	printf("请输入您所想寻找的联系人的名字\n");
	scanf("%s", arr);
	int i = FindByName(arr, pc);
	if (-1 == i)
	{
		printf("找不到\n");
		return;
	}

	//删除
	for (; i < pc->sz; i++)
	{
		pc->date[i] = pc->date[i + 1];
	}
	pc->sz--; //联系人减少一个
	printf("删除成功\n");
}
//用户名寻找 ( 删除联系人,查找联系人,修改联系人使用本函数 )
 FindByName(char* arr, Contact* pc)
{
	 assert(pc && arr);
	 for (int i = 0; i < pc->sz; i++)
	{
		if (0 == strcmp(arr, pc->date[i].name))
		{
			return i;
		}
	}
	return -1;
}

        代码涉及的一些小技巧:

  1.         我们这个代码有删除联系人,查找联系人,修改联系人此三个功能,皆是需要运用到联系人查找的。于是,对于用户名寻找最好是单独出一个函数来完成。
  2.          对于对错的判断,我们可以采取让常数在左侧,主要是这样可以避免一时失误,将 “ == ” 编写成 “ = ” 的尴尬,毕竟常数是不能被修改的,“ = ”必定会报警告,而不用此方法如果写错了,就会出现赋值成功,就返回赋得的值,就会出现一直答案错,却难以查找的Bug。这样非常不便于查找。

        需要注意的是,对于用户名寻找函数中,找到就返回该在数组中的下标,找不到一定要返回负数,毕竟,找到后返回的下标范围为 >=0 。(本人就因为习惯关系,将返回值定为0,然后以为是判断与交换的地方出错,耗费很多时间……)

5. 查找联系人

//查找联系人
void SearchContact(Contact* pc)
{
	assert(pc);
	char arr[20] = { 0 };
	printf("请输入您所想寻找的联系人的名字\n");
	scanf("%s", arr);
	int i = FindByName(arr, pc);
	if (-1 == i)
	{
		printf("找不到\n");
		return;
	}
	else
	{
		printf("找到了\n");
		printf("%-10s %-5s %-3s %-12s %-20s\n", "名字", "性别", "年龄", "电话", "地址");
		printf("%-10s %-5s %-3d %-12s %-20s\n", pc->date[i].name, pc->date[i].sex, pc->date[i].age, pc->date[i].tele, pc->date[i].addr);
	}
}

6. 修改联系人

//修改联系人
void ModifyContact(Contact* pc)
{
	assert(pc);
	char arr[20] = { 0 };
	printf("请输入您所想修改的联系人的名字\n");
	scanf("%s", arr);
	int i = FindByName(arr, pc);
	if (-1 == i)
	{
		printf("找不到\n");
		return;
	}
	else
	{
		printf("请输入您所修改的内容\n");
		printf("请输入名字:\n");
		scanf("%s", pc->date[i].name);
		printf("请输入性别:\n");
		scanf("%s", pc->date[i].sex);
		printf("请输入年龄:\n");
		scanf("%d", &(pc->date[i].age));
		printf("请输入电话:\n");
		scanf("%s", pc->date[i].tele);
		printf("请输入地址:\n");
		scanf("%s", pc->date[i].addr);
		printf("修改成功\n");

		printf("%-10s %-5s %-3s %-12s %-20s\n", "名字", "性别", "年龄", "电话", "地址");
		printf("%-10s %-5s %-3d %-12s %-20s\n", pc->date[i].name, pc->date[i].sex, pc->date[i].age, pc->date[i].tele, pc->date[i].addr);
	}
}

7. 联系人排序

//名字大小比较
int cmp(const void* e1, const void* e2)
{
	return strcmp(((Infotmation*)e1)->name, ((Infotmation*)e2)->name);
}

//联系人排序
void SortContact(Contact* pc)
{
	assert(pc);

	qsort(pc->date, pc->sz, sizeof(pc->date[0]), cmp);
	PrintContact(pc);
}

        在本人博客已经有关于qsort函数的介绍,以及qsort函数的冒泡排序的简易模仿。(不懂简易结合最后总代码理解)

8. 打印用户的信息

//打印用户的信息
void PrintContact(Contact* pc)
{
	assert(pc);

	printf("%-10s %-5s %-3s %-12s %-20s\n", "名字", "性别", "年龄", "电话", "地址");
	for (int i = 0; i < pc->sz; i++)
	{
		printf("%-10s %-5s %-3d %-12s %-20s\n", pc->date[i].name, pc->date[i].sex, pc->date[i].age, pc->date[i].tele, pc->date[i].addr);
	}
}

9. 总代码

        text.c

#define _CRT_SECURE_NO_WARNINGS 1

#include "contact.h"

void menu()
{
	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");
	printf("******请选择所需功能*******\n");
}

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

	//数据初始化
	InitContact(&Con);

	do
	{
		menu();
		scanf("%d", &input);
		switch (input)
		{
		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: //退出
			break;
		default:
			printf("输入错误,请重新输入\n");
			break;
		}
	} while (input);
	return 0;
}

        contact.h

#pragma once

#include 
#include 
#include 
#include 

#define MAX 1000 //联系人的存储上限

#define NAME_MAX 20 //名字的存储上限
#define SEX_MAX 3 //性别的存储上限
#define TELT_MAX 12 //电话的存储上限
#define ADDR_AMX 20 //地址的存储上限

typedef struct Infotmation
{
	char name[NAME_MAX]; //名字
	char sex[SEX_MAX]; //性别
	int age; //年龄
	char tele[TELT_MAX]; //电话
	char addr[ADDR_AMX]; //住址
}Infotmation;

typedef struct Contact
{
	Infotmation date[MAX];
	int sz;
}Contact;



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


//数据初始化
void InitContact(Contact* pc);

//增加联系人信息
void AddContact(Contact* pc);

//打印用户的信息
void PrintContact(Contact* pc);

//删除用户的信息
void DelContact(Contact* pc);

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

//修改联系人
void ModifyContact(Contact* pc);

//联系人排序
void SortContact(Contact* pc);

        contact.c

#define _CRT_SECURE_NO_WARNINGS 1

#include "contact.h"

//数据初始化
void InitContact(Contact* pc)
{
	assert(pc);
	pc->sz = 0;
	memset(pc->date, 0, sizeof(pc->date));
}

//增加联系人信息
void AddContact(Contact* pc)
{
	assert(pc);
	printf("请输入名字:\n");
	scanf("%s", pc->date[pc->sz].name);
	printf("请输入性别:\n");
	scanf("%s", pc->date[pc->sz].sex);
	printf("请输入年龄:\n");
	scanf("%d", &(pc->date[pc->sz].age));
	printf("请输入电话:\n");
	scanf("%s", pc->date[pc->sz].tele);
	printf("请输入地址:\n");
	scanf("%s", pc->date[pc->sz].addr);

	pc->sz++;
	printf("输入成功\n");
}

//打印用户的信息
void PrintContact(Contact* pc)
{
	assert(pc);
	printf("%-10s %-5s %-3s %-12s %-20s\n", "名字", "性别", "年龄", "电话", "地址");
	for (int i = 0; i < pc->sz; i++)
	{
		printf("%-10s %-5s %-3d %-12s %-20s\n", pc->date[i].name, pc->date[i].sex, pc->date[i].age, pc->date[i].tele, pc->date[i].addr);
	}
}

//寻找用户名
 FindByName(char* arr, Contact* pc)
{
	 assert(pc && arr);
	 for (int i = 0; i < pc->sz; i++)
	{
		if (0 == strcmp(arr, pc->date[i].name))
		{
			return i;
		}
	}
	return -1;
}

//删除用户的信息
void DelContact(Contact* pc)
{
	assert(pc);
	//查找
	char arr[20] = { 0 };
	printf("请输入您所想寻找的联系人的名字\n");
	scanf("%s", arr);
	int i = FindByName(arr, pc);
	if (-1 == i)
	{
		printf("找不到\n");
		return;
	}

	//删除
	for (; i < pc->sz; i++)
	{
		pc->date[i] = pc->date[i + 1];
	}
	pc->sz--;
	printf("删除成功\n");
}

//查找联系人
void SearchContact(Contact* pc)
{
	assert(pc);
	char arr[20] = { 0 };
	printf("请输入您所想寻找的联系人的名字\n");
	scanf("%s", arr);
	int i = FindByName(arr, pc);
	if (-1 == i)
	{
		printf("找不到\n");
		return;
	}
	else
	{
		printf("找到了\n");
		printf("%-10s %-5s %-3s %-12s %-20s\n", "名字", "性别", "年龄", "电话", "地址");
		printf("%-10s %-5s %-3d %-12s %-20s\n", pc->date[i].name, pc->date[i].sex, pc->date[i].age, pc->date[i].tele, pc->date[i].addr);
	}
}

//修改联系人
void ModifyContact(Contact* pc)
{
	assert(pc);
	char arr[20] = { 0 };
	printf("请输入您所想修改的联系人的名字\n");
	scanf("%s", arr);
	int i = FindByName(arr, pc);
	if (-1 == i)
	{
		printf("找不到\n");
		return;
	}
	else
	{
		printf("请输入您所修改的内容\n");
		printf("请输入名字:\n");
		scanf("%s", pc->date[i].name);
		printf("请输入性别:\n");
		scanf("%s", pc->date[i].sex);
		printf("请输入年龄:\n");
		scanf("%d", &(pc->date[i].age));
		printf("请输入电话:\n");
		scanf("%s", pc->date[i].tele);
		printf("请输入地址:\n");
		scanf("%s", pc->date[i].addr);
		printf("修改成功\n");

		printf("%-10s %-5s %-3s %-12s %-20s\n", "名字", "性别", "年龄", "电话", "地址");
		printf("%-10s %-5s %-3d %-12s %-20s\n", pc->date[i].name, pc->date[i].sex, pc->date[i].age, pc->date[i].tele, pc->date[i].addr);
	}
}
//名字大小比较
int cmp(const void* e1, const void* e2)
{
	return strcmp(((Infotmation*)e1)->name, ((Infotmation*)e2)->name);
}

//联系人排序
void SortContact(Contact* pc)
{
	assert(pc);

	qsort(pc->date, pc->sz, sizeof(pc->date[0]), cmp);
	PrintContact(pc);
}

你可能感兴趣的:(c语言)