Lenguaje C para realizar el sistema de gestión de la libreta de direcciones (estático y dinámico)

Las funciones realizadas son:

  1. Agregar información de contacto
  2. Mostrar toda la información de contacto
  3. Encuentre información de contacto específica
  4. Modificar la información de contacto especificada
  5. Eliminar la información de contacto especificada
  6. Borrar todos los contactos
  7. Ordenar todos los contactos
  8. Leer archivos de contactos
  9. Almacenar contactos en archivo

Se pueden realizar diferentes funciones de acuerdo con diferentes módulos.
 
 
 
Archivo de encabezado: main.h

#include <stdio.h>
#include <assert.h>
#include <string.h>
#pragma warning(disable:4996)
#define N 1000//电话簿大小
typedef struct Info
{
	char name[20];
	char sex[10];
	int age;
	char telephone[12];
	char address[20];
}Info;//定义结构体,包含的个人信息
typedef struct MailList
{
	Info data[N];
	int count;
}MailList;//定义电话簿结构体,包含计数和电话簿的大小
void InitiBook(MailList *pm);//初始化电话簿
void AddContact(MailList *pm);//添加联系人信息
void Check(int number);//校验电话簿是否满了
void DeleteContact(MailList *pm);//删除联系人信息
void SeekContact(MailList *pm);查找联系人信息
void ShowOneContact(MailList *pm, int number);//显示一个人的信息,方便在查询的时候,输出单一联系人的信息
void ModifyContact(MailList *pm);//修改联系人信息
void ShowContact(MailList *pm);//显示所有联系人信息
void ClearContact(MailList *pm);//清除联系人信息
void SortContact(MailList *pm);//排序联系人信息

 
 
 
Función principal: main.c

int main()
{
	menu();
	printf("请做出你的选择:>");
	int choice = 0;
	scanf("%d", &choice);
	MailList Book;//定义结构体
	InitiBook(&Book);//初始化结构体
	while (0 != choice)
	{
		switch (choice)
		{
		case 1:
			AddContact(&Book);
			break;
		case 2:
			ShowContact(&Book);
			break;
		case 3:
			SeekContact(&Book);
			break;
		case 4:
			ModifyContact(&Book);
			break;
		case 5:
			DeleteContact(&Book);
			break;
		case 6:
			ClearContact(&Book);
			break;
		case 7:
			SortContact(&Book);
			break;
		default:
			printf("你的输入有错误!\n");
			break;
		}
		menu();
		printf("\n请做出你的选择:>");
		scanf("%d", &choice);
	}
	return 0;
}

//在这里调用了一个菜单函数
void menu()
{
	printf("###########################################\n");
	printf("######      欢迎来到通讯录管理系统   ######\n");
	printf("######          0.退出               ######\n");
	printf("######      1.添加联系人信息         ######\n");
	printf("######      2.显示所有联系人信息     ######\n");
	printf("######      3.查找指定联系人信息     ######\n");
	printf("######      4.修改指定联系人信息     ######\n");
	printf("######      5.删除指定联系人信息     ######\n");
	printf("######      6.清空所有联系人         ######\n");
	printf("######      7.排序所有联系人         ######\n");
	printf("###########################################\n");

}

 
 
 
1. Función de inicialización: inicializa la estructura definida

void InitiBook(MailList *pm)
{
	pm->count = 0;
}

Simplemente establezca el recuento definido en 0 directamente.

 
 
 
2. Agregue el módulo de información de contacto: se debe evaluar la capacidad.

void AddContact(MailList *pm)
{
	assert(pm);//校验是否为空
	Check(pm->count);//判定容量
	printf("-----------------------------------------\n");
	printf("请输入名字:>");
	scanf("%s", &pm->data[pm->count].name);
	printf("\n请输入性别:>");
	scanf("%s", &pm->data[pm->count].sex);
	printf("\n请输入年龄:>");
	scanf("%d", &pm->data[pm->count].age);
	printf("\n请输入电话:>");
	scanf("%s", &pm->data[pm->count].telephone);
	printf("\n请输入住址:>");
	scanf("%s", &pm->data[pm->count].address);
	pm->count++;
	printf("-----------------------------------------\n");
}

 
 
 
3. Mostrar módulo de contacto: muestra directamente la información de contacto agregada.

void ShowContact(MailList *pm)
{
	assert(pm);
	printf("--------------------------------------------------------\n");
	int i = 0;
	for (; i < pm->count; i++)
	{
		printf("姓名:%s   ", pm->data[i].name);
		printf("性别:%s   ", pm->data[i].sex);
		printf("年龄:%d   ", pm->data[i].age);
		printf("电话:%s   ", pm->data[i].telephone);
		printf("住址:%s   ", pm->data[i].address);
		printf("\n");
	}
	printf("---------------------------------------------------------\n");
}

 
 
 
4. Modificar el módulo de información de contacto: puede modificar la información de contacto por separado.

void ModifyContact(MailList *pm)
{
	assert(pm);
	printf("请输入你要修改人的姓名:");
	char name[20];
	scanf("%s", &name);
	int i = 0;
	int judge = 0;
	for (; i < pm->count; i++)
	{
		if (0 == strcmp(name, pm->data[i].name))
		{
			printf("\n此人的信息为:\n");
			ShowOneContact(pm, i);
			menu2();
			printf("请输入你要修改的内容:");
			int choice = 0;
			scanf("%d", &choice);
			while (choice)
			{
				switch (choice)
				{
				case 1:
					printf("请输入修改的姓名:>");
					scanf("%s", &pm->data[i].name);
					ShowOneContact(pm, i);
					break;
				case 2:
					printf("请输入修改的性别:>");
					scanf("%s", &pm->data[i].sex);
					ShowOneContact(pm, i);
					break;
				case 3:
					printf("请输入修改的年龄:>");
					scanf("%d", &pm->data[i].age);
					ShowOneContact(pm, i);
					break;
				case 4:
					printf("请输入修改的电话:>");
					scanf("%s", &pm->data[i].telephone);
					ShowOneContact(pm, i);
					break;
				case 5:
					printf("请输入修改的住址:>");
					scanf("%s", &pm->data[i].address);
					ShowOneContact(pm, i);
					break;
				default:
					printf("输入错误,请重新输入!\n");
					break;
				}
				menu2();
				printf("请输入你要修改的内容:");
				scanf("%d", &choice);
			}
			printf("修改成功,此人的信息变为:>\n");
			ShowOneContact(pm, i);
			judge = 1;
		}
		if (1 == judge)
		{
			break;
		}
	}

	if (1 != judge)
	{
		printf("此人的信息不存在,无法修改\n");
	}
}

//调用的菜单函数
void menu2()
{
	printf("\n##################################\n");
	printf("######        0.退出        ######\n");
	printf("######      1.姓名修改      ######\n");
	printf("######      2.性别修改      ######\n");
	printf("######      3.年龄修改      ######\n");
	printf("######      4.电话修改      ######\n");
	printf("######      5.住址修改      ######\n");
	printf("##################################\n");

}

 
 
 
5. Eliminar módulo de información de contacto designado: elimina el nombre del contacto designado.

void DeleteContact(MailList *pm)
{
	assert(pm);
	printf("请输入你要删除人的姓名:");
	char name[20];
	scanf("%s", &name);
	int i = 0;
	int judge = 0;
	for (; i < pm->count; i++)
	{
		if (0 == strcmp(name, pm->data[i].name))
		{
			pm->data[i] = pm->data[i + 1];
			judge = 1;
		}
	}
	if (1 == judge)
	{
		printf("删除成功!\n");
		pm->count--;//删除成功,计数减1
	}
	else
	{
		printf("此人的信息不存在,无法删除\n");
	}
}

 
 
 
6. Borrar información de contacto: para borrar toda la información de contacto, establezca directamente el recuento en 0.

void ClearContact(MailList *pm)
{
	assert(pm);
	pm->count = 0;
}

 
 
 
7. Clasificación de la información de los contactos: hay varias formas de clasificar los contactos por separado.

void SortContact(MailList *pm)
{
	assert(pm);
	ShowContact(pm);
	menu3();
	printf("选择你排序的方式:>");
	int choice = 0;
	scanf("%d", &choice);
	switch (choice)
	{
	case 1:
		printf("\n以名字排序:>\n");
		BubbleSort(pm,pm->count, sizeof(Info),cmp_name);
		ShowContact(pm);
		break;
	case 2:
		printf("\n以性别排序:>\n");
		BubbleSort(pm, pm->count, sizeof(Info), cmp_sex);
		ShowContact(pm);
		break;
	case 3:
		printf("\n以年龄排序:>\n");
		BubbleSort(pm, pm->count, sizeof(Info), cmp_age);
		ShowContact(pm);
		break;
	case 4:
		printf("\n以电话排序:>\n");
		BubbleSort(pm, pm->count, sizeof(Info), cmp_telephone);
		ShowContact(pm);
		break;
	case 5:
		printf("\n以住址排序:>\n");
		BubbleSort(pm, pm->count, sizeof(Info), cmp_address);
		ShowContact(pm);
		break;
	default:
		printf("输入的选择有误!\n");
		break;
	}
}


int cmp_name(const void *s1, const void *p1)
{
	MailList *s2 = (MailList *)s1;
	MailList *p2 = (MailList *)p1;
	return strcmp(s2->data->name, p2->data->name);
}
int cmp_age(const void *s1, const void *p1)
{
	MailList *s2 = (MailList *)s1;
	MailList *p2 = (MailList *)p1;
	if ((s2->data->age - p2->data->age) > 0)
	{
		return 1;
	}
	else
	{
		return -1;
	}
}
int cmp_sex(const void *s1, const void *p1)
{
	MailList *s2 = (MailList *)s1;
	MailList *p2 = (MailList *)p1;
	return strcmp(s2->data->sex, p2->data->sex);
}
int cmp_telephone(const void *s1, const void *p1)
{
	MailList *s2 = (MailList *)s1;
	MailList *p2 = (MailList *)p1;
	return strcmp(s2->data->telephone, p2->data->telephone);
}
int cmp_address(const void *s1, const void *p1)
{
	MailList *s2 = (MailList *)s1;
	MailList *p2 = (MailList *)p1;
	return strcmp(s2->data->address, p2->data->address);
}

void Swap(char *s1, char *s2, int width)
{
	int i = 0;
	for (; i < width; i++)
	{
		s1[i] ^= s2[i];
		s2[i] ^= s1[i];
		s1[i] ^= s2[i];
	}
}

void BubbleSort(void *base, int number, int width, int (*cmp)(const void *p, const void *p2))
{
	int i = 0;
	int j = 0;
	for (; i < number; i++)
	{
		for (j = 0; j < number - i - 1; j++)
		{
			if (cmp((char *)base + width * j, (char *)base + width * (j + 1))>0)
			{
				Swap((char *)base + width * j, (char *)base + width * (j + 1),width);
			}

		}
	}
}

//调用的菜单函数
void menu3()
{
	printf("\n####################################\n");
	printf("######      0.不排序          ######\n");
	printf("######      1.以姓名排序      ######\n");
	printf("######      2.以性别排序      ######\n");
	printf("######      3.以年龄排序      ######\n");
	printf("######      4.以电话排序      ######\n");
	printf("######      5.以住址排序      ######\n");
	printf("####################################\n");
}

Puede elegir 5 formas de ordenar los contactos. Aquí, una función de devolución de llamada y un método de clasificación de burbujas se utilizan para ordenar la libreta de direcciones.

 
 
 
El método de realización anterior es realización estática, que no es perfecta. Si la agenda telefónica requerida es relativamente pequeña, abre mucho espacio y provoca una pérdida de espacio. Por lo tanto, el método de apertura dinámica de espacio es más flexible.

Solo por el código anterior. Solo una pequeña mejora.

typedef struct MailList
{
	Info *data; //在这里修改为指针
	int count;
	int capacity;
}MailList;

void InitiBook(MailList *pm)//初始化的时候,定义电话簿的大小
{
	pm->count = 0;
	pm->capacity = 3;//电话薄的大小,可以任意配置。
	pm->data = (Info *)malloc(sizeof(Info) * pm->capacity);//开辟空间
}

int Check(MailList *pm)//电话簿容量判断
{
	if (pm->capacity -1 < pm->count)
	{
		printf("通讯录容量超过限制,不可再继续添加!\n");
		return 1;
	}
	return 0;
}

void AddContact(MailList *pm)
{
	assert(pm);
	int ret=Check(pm);//这里进行了修改
	if (1 == ret)
	{
		exit(EXIT_FAILURE);
	}
	printf("-----------------------------------------\n");
	printf("请输入名字:>");
	scanf("%s", &pm->data[pm->count].name);
	printf("\n请输入性别:>");
	scanf("%s", &pm->data[pm->count].sex);
	printf("\n请输入年龄:>");
	scanf("%d", &pm->data[pm->count].age);
	printf("\n请输入电话:>");
	scanf("%s", &pm->data[pm->count].telephone);
	printf("\n请输入住址:>");
	scanf("%s", &pm->data[pm->count].address);
	pm->count++;
	printf("-----------------------------------------\n");
}

No se pueden realizar cambios en otros lugares.
El código completo se puede descargar aquí: Realización dinámica de la libreta de direcciones

 
 
 
Al realizar operaciones de seguimiento, se encontró que la implementación del séptimo módulo era problemática y se cambió el código:

int cmp_name(const Info *s1, const Info *p1)
{
	return strcmp(s1->name, p1->name);
}
int cmp_age(const Info *s1, const Info *p1)
{
	if ((s1->age - p1->age) > 0)
	{
		return 1;
	}
	else
	{
		return -1;
	}
}
int cmp_sex(const Info *s1, const Info *p1)
{
	return strcmp(s1->sex, p1->sex);
}
int cmp_telephone(const Info *s1, const Info *p1)
{
	return strcmp(s1->telephone, p1->telephone);
}
int cmp_address(const Info *s1, const Info *p1)
{
	return strcmp(s1->address, p1->address);
}

void Swap(void *s1, void *s2, int width)
{
	int i = 0;
	char *s3 = (char *)s1;
	char *s4 = (char *)s2;
	for (; i < width; i++)
	{
		s3[i] ^= s4[i];
		s4[i] ^= s3[i];
		s3[i] ^= s4[i];
	}
}

void BubbleSort(MailList *base, int number, int width, int(*cmp)(const Info *p, const Info *p2))
{
	int i = 0;
	int j = 0;
	for (; i < number; i++)
	{
		for (j = 0; j < number - i - 1; j++)
		{
			if (cmp(&base->data[j], &base->data[j+1]) > 0)
			{
				Swap(&base->data[j], &base->data[j+1],width);
			}

		}
	}
}

La razón de este problema es que la comprensión del puntero de la estructura interna no es lo suficientemente clara, lo que provocó este error. El código anterior ha sido modificado.

 
 
 
 
 
 
Más tarde se agregaron dos módulos: leer datos de archivo y almacenar datos para
modificar el código de archivo :

void menu()//菜单函数修改
{
	printf("###########################################\n");
	printf("######      欢迎来到通讯录管理系统   ######\n");
	printf("######          0.退出               ######\n");
	printf("######      1.添加联系人信息         ######\n");
	printf("######      2.显示所有联系人信息     ######\n");
	printf("######      3.查找指定联系人信息     ######\n");
	printf("######      4.修改指定联系人信息     ######\n");
	printf("######      5.删除指定联系人信息     ######\n");
	printf("######      6.清空所有联系人         ######\n");
	printf("######      7.排序所有联系人         ######\n");
	printf("######      8.读取文件联系人         ######\n");
	printf("######      9.存储联系人到文件       ######\n");
	printf("###########################################\n");

}
case 8:
	ReadContact(&Book);
	break;
case 9:
	SaveContact(&Book);
	break;//switch语句里面进行了修改
void ReadContact(MailList *pm);
void SaveContact(MailList *pm);//两个声明
int Check(MailList *pm)
{
	if (pm->capacity -1 < pm->count)
	{
		printf("通讯录容量超过限制,不可再继续添加!\n");
		printf("是否选择扩容!\n");
		menu4();
		int choice = 0;
		scanf("%d", &choice);
		Info *ptr = NULL;
		switch (choice)
		{
		case 1:
			ptr = realloc(pm->data,sizeof(Info) * pm->capacity * 2);
			if (NULL != ptr)
			{
				pm->data = ptr;
				pm->capacity = 2 * pm->capacity;
				printf("扩容成功!\n");
				return 0;
			}
		case 2:
			return 1;
		default:
			printf("您的输入有误!\n");
			break;
		}
		return 1;
	}
	return 0;
}//校验函数进行了修改,如果容量不够,进行扩容


void ReadContact(MailList *pm)//读取文件数据
{
	int c = 0;
	int judge = 0;
	FILE *fp = fopen("PhoneBook.txt", "r");
	if (NULL == fp)
	{
		perror("file open failed");
		exit(0);
	}
	while (1)
	{
		judge=Check(pm);
		if (0 == judge)
		{
			fscanf(fp, "%s", pm->data[pm->count].name);
			fscanf(fp, "%s", pm->data[pm->count].sex);
			fscanf(fp, "%d", &pm->data[pm->count].age);
			fscanf(fp, "%s", pm->data[pm->count].telephone);
			fscanf(fp, "%s", pm->data[pm->count].address);
			pm->count++;
		}
		else 
		{
			printf("未完全读取!\n");
			break;
		}
		if ((c=fgetc(fp)) == EOF)
		{
			pm->count--;
			printf("信息读取成功\n");
			break;
		}
	}
	fclose(fp);
}

void SaveContact(MailList *pm)//存储联系人到文件
{
	FILE *fp = fopen("PhoneBook.txt", "w");
	if (NULL == fp)
	{
		perror("file open failed");
		exit(0);
	}
	for (int i = 0; i < pm->count; i++)
	{
		fprintf(fp, "%s\t", pm->data[i].name);
		fprintf(fp, "%s\t", pm->data[i].sex);
		fprintf(fp, "%d\t", pm->data[i].age );
		fprintf(fp, "%s\t", pm->data[i].telephone );
		fprintf(fp, "%s", pm->data[i].address );
		fprintf(fp, "\n");
	}
	printf("\n联系人存储成功!\n");
	fclose(fp);
}
//扩容时,调用了一个菜单函数
void menu4()
{
	printf("\n####################################\n");
	printf("######         1.扩容          ######\n");
	printf("######         2.不扩容        ######\n");
	printf("####################################\n");
}

El código anterior puede completar las funciones de estos dos módulos. Los procedimientos específicos también se cargan en el sitio web vinculado anteriormente.
El código completo se puede descargar aquí: Realización dinámica de la libreta de direcciones

Supongo que te gusta

Origin blog.csdn.net/w903414/article/details/106907767
Recomendado
Clasificación