Implementação do catálogo de endereços [linguagem C]

Índice

Prefácio

1. Análise lógica geral

2. Etapas de implementação

1. Problemas com a criação de menus e múltiplas operações

2. Crie um catálogo de endereços

3. Inicialize o catálogo de endereços

4. Adicione contatos

5. Exibir contatos

6. Exclua os contatos especificados

7. Encontre a pessoa de contato designada

8. Modifique as informações de contato

9. Classifique as informações de contato

3. Todo o código-fonte


Prefácio

Introduzimos os tipos personalizados em detalhes na última edição. Nesta edição, usaremos o conhecimento que aprendemos para colocar em prática um pequeno projeto. Nesta edição usaremos a linguagem C para implementar uma versão estática do catálogo de endereços! O gerenciamento dinâmico de memória e as operações de arquivo serão introduzidos posteriormente. Iremos otimizar e melhorar com base nesta versão!

1. Análise lógica geral

Assim como antes, quando implementamos os pequenos projetos do xadrez de três peças e do caça-minas, primeiro analisamos a lógica do projeto geral com o máximo de detalhes possível. Caso contrário, seria um tapa na cara no início, e seria seria ruim descobrir que no final eram todos bugs! Analisamos da forma mais clara possível no início, para que mesmo que haja problemas posteriormente, possamos identificá-los rapidamente! Esta edição ainda usa programação multi-arquivo como nas edições anteriores! OK, vamos resolver a lógica básica de implementação deste pequeno projeto:

1. Problemas com a criação de menus e múltiplas operações

2. Crie um catálogo de endereços

3. Inicialização do catálogo de endereços e operações como adição, exclusão, verificação e modificação

2. Etapas de implementação

1. Problemas com a criação de menus e múltiplas operações

Esperamos que, ao operar o catálogo de endereços, possamos receber uma função de menu antes da operação! Considerando que precisaremos operar o catálogo de endereços muitas vezes no futuro (adicionando, excluindo, verificando, modificando, etc.), rapidamente pensamos em usar um loop do..while para processá-lo. Escrevemos isso duas ou três vezes. vezes antes, então codificamos diretamente:

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

void test()
{
	int input = 0;
	do
	{
		menu();
		printf("请选择操作数:> ");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			//add
			break;
		case 2:
			//del
			break;
		case 3:
			//search
			break;
		case 4:
			//modify
			break;
		case 5:
			//show
			break;
		case 6:
			//sort
			break;
		case 0:
			printf("退出成功!\n");
			break;
		default:
			printf("选择数非法!\n");
			break;
		}

	} while (input);
}

int main()
{
	test();
	return 0;
}

Veja o efeito:

2. Crie um catálogo de endereços

Antes de realizarmos várias operações no catálogo de endereços, precisamos primeiro ter um catálogo de endereços! A essência do catálogo de endereços é descrever os atributos de uma pessoa como: nome, idade, sexo, número de telefone, endereço, etc.! São todos tipos diferentes e podemos facilmente pensar em usar estruturas para resolvê-los! Mas isso é apenas a descrição de uma pessoa. Não pode haver apenas uma pessoa em sua agenda. Deve haver muitas! E esses contatos são do mesmo tipo, então uma estrutura array é usada para criar o catálogo de endereços!

typedef struct PeoInfo
{
	char name[20];
	int age;
	char sex[5];
	char tele[15];
	char addr[20];
}PeoInfo;

Esta é uma estrutura que descreve os atributos básicos de uma pessoa! Depois de criar essa estrutura, podemos criar um array de estrutura como um catálogo de endereços no loop do..while no arquivo test.c!

Mas há um problema em escrever desta forma: quando você salva ou apaga um contato e quer imprimi-lo para ver se é o contato da agenda naquele momento, quanto você deve imprimir? Ainda nos perguntamos. Então aqui temos que definir outra variável sz para registrar o tamanho do catálogo de endereços!

Na verdade, descobrimos que sz não só pode registrar o tamanho do catálogo de endereços, mas também ao adicionar contatos, você só precisa aumentá-lo para a posição sz, adicionar um sz++ e excluir um sz--; desta forma, sz e o catálogo de endereços estão realmente vinculados a Ao mesmo tempo, podemos também encapsular o catálogo de endereços em uma estrutura.Um membro é a matriz da estrutura PeoInfo e o outro é sz que registra o tamanho do catálogo de endereços:

typedef struct PeoInfo
{
	char name[20];
	int age;
	char sex[5];
	char tele[15];
	char addr[20];
}PeoInfo;


typedef struct Contact
{
	PeoInfo data[100];
	int sz;
}Contact;

Em seguida, crie-o no arquivo test.c!

OK! Este catálogo de endereços é criado e registrado! Na verdade, ainda podemos fazer uma pequena otimização aqui: descobrimos que existem muitas constantes em ambas as estruturas. Se as nossas necessidades mudarem mais tarde, estas terão que ser alteradas! Portanto, para conveniência de modificação posterior, nós as alteramos para constantes #define, que serão fáceis de modificar posteriormente! Aqui você pode dizer que as enumerações foram introduzidas na última edição. Não seria melhor ter múltiplas enumerações constantes aqui? A enumeração aqui pode de fato atingir o objetivo, mas enumerar é enumerar todas as possibilidades antes de começar, o que não é o caso da nossa! Então, não há necessidade de enumerar aqui!

#define NAME_MAX 20
#define SEX_MAX 5
#define TELE_MAX 15
#define ADDR_MAX 20
#define MAX 100

typedef struct PeoInfo
{
	char name[NAME_MAX];
	int age;
	char sex[SEX_MAX];
	char tele[TELE_MAX];
	char addr[ADDR_MAX];
}PeoInfo;


typedef struct Contact
{
	PeoInfo data[MAX];
	int sz;
}Contact;

Este é o código ideal sob a lógica atual!

3. Inicialize o catálogo de endereços

Depois de criarmos o catálogo de endereços, primeiro o inicializamos! Inicialize cada elemento da matriz de estrutura como 0 e defina o tamanho do catálogo de endereços como 0! Porque queremos alterar o conteúdo da estrutura, devemos passar o endereço! O que usamos aqui é que a função memset é inicializada diretamente em 0 ou pode ser inicializada com um loop! Clique em memset se você não entende memset

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

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

4. Adicione contatos

Como dissemos antes, só precisamos aumentar a posição de sz! Mas considere a situação quando a agenda está cheia!

void AddContact(Contact* pc) 
{
	assert(pc);
	//通讯录已满
	if (pc->sz == MAX)
	{
		printf("通讯录已满,无法添加!\n");
		return;
	}

	//添加联系人
	printf("请输入联系人姓名:> ");
	scanf("%s", pc->data[pc->sz].name);
	printf("请输入联系人年龄:> ");
	scanf("%d", &pc->data[pc->sz].age);
	printf("请输入联系人性别:> ");
	scanf("%s", pc->data[pc->sz].sex);
	printf("请输入联系人电话:> ");
	scanf("%s", pc->data[pc->sz].tele);
	printf("请输入联系人住址:> ");
	scanf("%s", pc->data[pc->sz].addr);
	pc->sz++;

	printf("添加成功!\n");
}

OK, vamos primeiro escrever um contato de exibição para verificar se ele foi adicionado com sucesso!

5. Exibir contatos

Exibir contatos significa imprimir os contatos do catálogo de endereços do console!

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

	printf("%-s\t%-s\t%-5s\t%-15s\t%-20s\n", "姓名", "年龄", "性别", "电话", "住址");
	for (int i = 0; i < pc->sz; i++)
	{
		printf("%-s\t%-d\t%-5s\t%-15s\t%-20s\n",
			pc->data[i].name,
			pc->data[i].age,
			pc->data[i].sex,
			pc->data[i].tele,
			pc->data[i].addr
		);
	}
}

OK, vamos ver se a adição foi bem-sucedida e os contatos são exibidos!

OK, a adição e exibição de contatos foram bem-sucedidas! Isso mostra que não há problema com nossa lógica acima!

6. Exclua os contatos especificados

Inserimos o nome da pessoa que queremos excluir, pesquisamos e excluímos, caso contrário, esse contato não existe na saída! Por favor, considere a situação quando o catálogo de endereços está vazio! Aqui se menciona a pesquisa. Esta pesquisa é um pouco diferente da pesquisa na agenda, esta só precisa retornar o subscrito após a pesquisa, enquanto a outra tem uma função diferente de imprimir informações de contato. Portanto, estamos encapsulando apenas uma função!

//查找要删除的人并返回下标
int FindContact(const Contact* pc, const char* name)
{
	for (int i = 0; i < pc->sz; i++)
	{
		if (strcmp(pc->data[i].name, name) == 0)
		{
			return i;//找到了
		}
	}

	return -1;//没找到
}

//删除联系人
void DelContact(Contact* pc)
{
	assert(pc);
    //通讯录为空
	if (pc->sz == 0)
	{
		printf("通讯录为空,无法删除!\n");
		return;
	}

	char name[NAME_MAX] = { 0 };
	printf("请输入要删除人的姓名:> ");
	scanf("%s", name);

	int pos = FindContact(pc, name);

	if (pos != -1)
	{
		//删除
		for (int i = pos; i < pc->sz - 1; i++)
		{
			pc->data[i] = pc->data[i + 1];
		}

		pc->sz--;
		printf("成功删除联系人!\n");
	}
	else
	{
		printf("没有此联系人!\n");
	}
}

O que deve ser observado aqui é que strcmp deve ser usado para comparar strings, e == não pode ser usado. Apresentamos isso em detalhes na edição de funções de string e funções de memória! Preste também atenção ao problema do subscrito fora dos limites ao excluir!

Veja o efeito:

 7. Encontre a pessoa de contato designada

Para encontrar o contato especificado, você deve primeiro pesquisar no método especificado. Se encontrado, imprima-o, caso contrário a saída não incluirá este contato! Esta página que exibe um contato aqui também pode ser usada para modificar o contato posteriormente, então, por conveniência, nós o encapsulamos em uma função e a chamamos diretamente!


//显示单个联系人信息
void Print(const Contact* pc, int pos)
{
	assert(pc);

	printf("%-s\t%-s\t%-5s\t%-15s\t%-20s\n", "姓名", "年龄", "性别", "电话", "住址");

	printf("%-s\t%-d\t%-5s\t%-15s\t%-20s\n",
		pc->data[pos].name,
		pc->data[pos].age,
		pc->data[pos].sex,
		pc->data[pos].tele,
		pc->data[pos].addr);

}

//查找指定联系人
void Search(const Contact* pc)
{
	assert(pc);

	char name[NAME_MAX] = { 0 };
	printf("请输入要查找联系人姓名:> ");
	scanf("%s", name);

	int pos = -1;//初始化为-1表示没有此联系人
	for (int i = 0; i < pc->sz; i++)
	{
		if (strcmp(pc->data[i].name, name) == 0)
		{
			pos = i;//找到了
			break;
		}
	}

	if (pos != -1)
	{
		Print(pc, pos);
	}
	else
	{
		printf("没有此联系人!\n");
	}
}

Na verdade, pode ser mais conciso. FindContact foi implementado acima e podemos usá-lo:

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

	char name[NAME_MAX] = { 0 };
	printf("请输入要查找联系人姓名:> ");
	scanf("%s", name);

	int pos = FindContact(pc, name);

	if (pos != -1)
	{
		Print(pc, pos);
	}
	else
	{
		printf("没有此联系人!\n");
	}
}

Veja o efeito:

8. Modifique as informações de contato

Existem muitas possibilidades para modificar informações de contato, por exemplo, você pode modificar apenas um item, como nome ou sexo, ou pode modificar vários itens, como nome, idade, etc., ou pode ter que modificar todas essas situações. Quando queremos modificar algo, ainda podemos esperar ter um menu para escolhermos e, após modificar um item, ainda podemos querer continuar modificando-o. Com base nisso, adotamos o menu do...while loop + no arquivo test.c!

//修改联系人信息菜单
void menu1()
{
    system("cls");
	printf("*****************************************\n");
	printf("********* 1. name     2. age   **********\n");
	printf("********* 3. sex      4. tele  **********\n");
	printf("********* 5. addr     6. all   **********\n");
	printf("********* 0. exit              **********\n");
	printf("*****************************************\n");
}

//修改名字
void ModName(Contact* pc, int ret)
{
	assert(pc);

	printf("请输入修改后联系人姓名:> ");
	scanf("%s", pc->data[ret].name);
	printf("修改成功!\n");
}

//修改年龄
void ModAge(Contact* pc, int ret)
{
	assert(pc);

	printf("请输入修改后联系人年龄:> ");
	scanf("%d", &pc->data[ret].age);
	printf("修改成功!\n");
}

//修改性别
void ModSex(Contact* pc, int ret)
{
	assert(pc);

	printf("请输入修改后联系人性别:> ");
	scanf("%s", &pc->data[ret].sex);
	printf("修改成功!\n");
}

//修改电话
void ModTele(Contact* pc, int ret)
{
	assert(pc);

	printf("请输入修改后联系人电话:> ");
	scanf("%s", &pc->data[ret].tele);
	printf("修改成功!\n");
}

//修改住址
void ModAddr(Contact* pc, int ret)
{
	assert(pc);

	printf("请输入修改后联系人住址:> ");
	scanf("%s", &pc->data[ret].addr);
	printf("修改成功!\n");
}


void ModAll(Contact* pc, int ret)
{
	assert(pc);

	printf("请输入联系人姓名:> ");
	scanf("%s", pc->data[ret].name);
	printf("请输入联系人年龄:> ");
	scanf("%d", &pc->data[ret].age);
	printf("请输入联系人性别:> ");
	scanf("%s", pc->data[ret].sex);
	printf("请输入联系人电话:> ");
	scanf("%s", pc->data[ret].tele);
	printf("请输入联系人住址:> ");
	scanf("%s", pc->data[ret].addr);
	
	printf("修改成功!\n");
}


//修改联系人
void ModContact(Contact* pc)
{
	assert(pc);
	//判断是否为空
	if (pc->sz == 0)
	{
		printf("通讯录为空,无法修改!\n");
		return;
	}

	char name[NAME_MAX] = { 0 };
	printf("请输入要修改系人姓名:> ");
	scanf("%s", name);
	//判断是否有该联系人
	int ret = FindContact(pc, name);
	
	//有该联系人
	if (ret != -1)
	{
		int n = 0;
		do
		{
			menu1();
			printf("请选择修改内容:> ");
			scanf("%d", &n);
			//修改
			switch (n)
			{
			case 1:
				ModName(pc,ret);
				break;
			case 2:
				ModAge(pc, ret);
				break;
			case 3:
				ModSex(pc, ret);
				break;
			case 4:
				ModTele(pc, ret);
				break;
			case 5:
				ModAddr(pc, ret);
				break;
			case 6:
				ModAll(pc, ret);
				break;
			case 0:
				printf("修改结束!\n");
				break;
			default:
				printf("选择数非法!\n");
				break;
			}

		} while (n);
	}
	else
	{
		printf("没有此联系人!\n");
	}
}

Veja o efeito: (O editor limpou a tela)

antes de consertar:

 Após modificação:

OK, foi um sucesso! Vamos resolver isso de novo!

9. Classifique as informações de contato

Já implementamos a função básica de adicionar, excluir, verificar e modificar o catálogo de endereços acima! Queremos que ele tenha outra função de ordenação, como ordenar por nome, ou ordenar por idade! Introduzimos a função de retorno de chamada na seção de avanço do ponteiro. Aqui usamos qsort para classificar o catálogo de endereços! Esperamos que ainda haja uma seleção de menu no início, como acima!


//排序菜单
void menu2()
{
	system("cls");
	printf("**********************************\n");
	printf("***** 1. name    2. age **********\n");
	printf("**********************************\n");
}

//名字比较函数
int cmp_name(const void* str1, const void* str2)
{
	//return strcmp(((PeoInfo*)str1)->name, ((PeoInfo*)str2)->name);
	return strcmp((((Contact*)str1)->data)->name, (((Contact*)str2)->data)->name);
}

//名字排序
void SortName(Contact* pc)
{
	qsort(pc->data, pc->sz, sizeof(pc->data[0]), cmp_name);
}

//年龄比较函数
int cmp_age(const void* str1, const void* str2)
{

	//return ((PeoInfo*)str1)->age - ((PeoInfo*)str2)->age;
	return (((Contact*)str1)->data)->age - (((Contact*)str2)->data)->age;
}
//年龄排序
void SortAge(Contact* pc)
{
	qsort(pc->data, pc->sz, sizeof(pc->data[0]), cmp_age);
}

//排序联系人信息
void SortContact(Contact* pc)
{
	assert(pc);
	//判断为空
	if (pc->sz == 0)
	{
		printf("通讯录为空,无法排序!\n");
		Sleep(3000);
		system("cls");
		return;
	}


	menu2();
	int n = 0;
	printf("请选择排序方式:> ");
	scanf("%d", &n);
	//排序
	switch (n)
	{
	case 1:
		SortName(pc);
		system("cls");
		printf("排序成功!\n");
		break;
	case 2:
		SortAge(pc);
		system("cls");
		printf("排序成功!\n");
		break;
	default:
		printf("选择数非法!\n");
		Sleep(3000);
		system("cls");
		break;
	}
}

Veja o efeito:

Antes de classificar (idade):

 Após classificação (idade):

Antes de classificar (nome):

 Depois de classificar (nome):

OK, a classificação está implementada!

3. Todo o código-fonte

 contato.h

#define _CRT_SECURE_NO_WARNINGS 1
#pragma once
#include<stdio.h>
#include<string.h>
#include<assert.h>
#include<stdlib.h>
#include<windows.h>

#define NAME_MAX 20
#define SEX_MAX 5
#define TELE_MAX 15
#define ADDR_MAX 20
#define MAX 100

typedef struct PeoInfo
{
	char name[NAME_MAX];
	int age;
	char sex[SEX_MAX];
	char tele[TELE_MAX];
	char addr[ADDR_MAX];
}PeoInfo;


typedef struct Contact
{
	PeoInfo data[MAX];
	int sz;
}Contact;


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

//添加联系人
void AddContact(Contact* pc);

//显示联系人
void ShowContact(const Contact* pc);

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

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

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

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


contato.c

#include"contact.h"

//初始化通讯录
void InitContact(Contact* pc)
{
	assert(pc);

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

//增加联系人
void AddContact(Contact* pc) 
{
	assert(pc);
	//通讯录已满
	if (pc->sz == MAX)
	{
		printf("通讯录已满,无法添加!\n");
		Sleep(2000);
		return;
	}

	//添加联系人
	printf("请输入联系人姓名:> ");
	scanf("%s", pc->data[pc->sz].name);
	printf("请输入联系人年龄:> ");
	scanf("%d", &pc->data[pc->sz].age);
	printf("请输入联系人性别:> ");
	scanf("%s", pc->data[pc->sz].sex);
	printf("请输入联系人电话:> ");
	scanf("%s", pc->data[pc->sz].tele);
	printf("请输入联系人住址:> ");
	scanf("%s", pc->data[pc->sz].addr);
	pc->sz++;

	printf("添加成功!\n");
	Sleep(1000);
}

//显示联系人
void ShowContact(const Contact* pc)
{
	assert(pc);

	printf("%-s\t%-s\t%-5s\t%-15s\t%-20s\n", "姓名", "年龄", "性别", "电话", "住址");
	for (int i = 0; i < pc->sz; i++)
	{
		printf("%-s\t%-d\t%-5s\t%-15s\t%-20s\n",
			pc->data[i].name,
			pc->data[i].age,
			pc->data[i].sex,
			pc->data[i].tele,
			pc->data[i].addr
		);
	}
}


//查找要删除的人并返回下标
int FindContact(const Contact* pc, const char* name)
{
	for (int i = 0; i < pc->sz; i++)
	{
		if (strcmp(pc->data[i].name, name) == 0)
		{
			return i;//找到了
		}
	}

	return -1;//没找到
}

//删除联系人
void DelContact(Contact* pc)
{
	assert(pc);
	if (pc->sz == 0)
	{
		printf("通讯录为空,无法删除!\n");
		Sleep(2000);
		return;
	}

	char name[NAME_MAX] = { 0 };
	printf("请输入要删除人的姓名:> ");
	scanf("%s", name);

	int pos = FindContact(pc, name);

	if (pos != -1)
	{
		//删除
		for (int i = pos; i < pc->sz - 1; i++)
		{
			pc->data[i] = pc->data[i + 1];
		}

		pc->sz--;
		printf("成功删除联系人!\n");
		Sleep(1000);
	}
	else
	{
		printf("没有此联系人!\n");
		Sleep(2000);
	}
}



//显示单个联系人信息
void Print(const Contact* pc, int pos)
{
	assert(pc);

	printf("%-s\t%-s\t%-5s\t%-15s\t%-20s\n", "姓名", "年龄", "性别", "电话", "住址");

	printf("%-s\t%-d\t%-5s\t%-15s\t%-20s\n",
		pc->data[pos].name,
		pc->data[pos].age,
		pc->data[pos].sex,
		pc->data[pos].tele,
		pc->data[pos].addr);

}

//查找指定联系人
void Search(const Contact* pc)
{
	assert(pc);

	char name[NAME_MAX] = { 0 };
	printf("请输入要查找联系人姓名:> ");
	scanf("%s", name);

	int pos = FindContact(pc, name);
	if (pos != -1)
	{
		Print(pc, pos);
	}
	else
	{
		printf("没有此联系人!\n");
		Sleep(2000);
		system("cls");
	}
}


//修改联系人信息菜单
void menu1()
{
	system("cls");
	printf("*****************************************\n");
	printf("********* 1. name     2. age   **********\n");
	printf("********* 3. sex      4. tele  **********\n");
	printf("********* 5. addr     6. all   **********\n");
	printf("********* 0. exit              **********\n");
	printf("*****************************************\n");
}

//修改名字
void ModName(Contact* pc, int ret)
{
	assert(pc);

	printf("请输入修改后联系人姓名:> ");
	scanf("%s", pc->data[ret].name);
}

//修改年龄
void ModAge(Contact* pc, int ret)
{
	assert(pc);

	printf("请输入修改后联系人年龄:> ");
	scanf("%d", &pc->data[ret].age);
}

//修改性别
void ModSex(Contact* pc, int ret)
{
	assert(pc);

	printf("请输入修改后联系人性别:> ");
	scanf("%s", &pc->data[ret].sex);
}

//修改电话
void ModTele(Contact* pc, int ret)
{
	assert(pc);

	printf("请输入修改后联系人电话:> ");
	scanf("%s", &pc->data[ret].tele);
}

//修改住址
void ModAddr(Contact* pc, int ret)
{
	assert(pc);

	printf("请输入修改后联系人住址:> ");
	scanf("%s", &pc->data[ret].addr);
}


void ModAll(Contact* pc, int ret)
{
	assert(pc);

	printf("请输入联系人姓名:> ");
	scanf("%s", pc->data[ret].name);
	printf("请输入联系人年龄:> ");
	scanf("%d", &pc->data[ret].age);
	printf("请输入联系人性别:> ");
	scanf("%s", pc->data[ret].sex);
	printf("请输入联系人电话:> ");
	scanf("%s", pc->data[ret].tele);
	printf("请输入联系人住址:> ");
	scanf("%s", pc->data[ret].addr);
}


//修改联系人
void ModContact(Contact* pc)
{
	assert(pc);
	//判断是否为空
	if (pc->sz == 0)
	{
		printf("通讯录为空,无法修改!\n");
		Sleep(2000);
		system("cls");
		return;
	}

	char name[NAME_MAX] = { 0 };
	printf("请输入要修改系人姓名:> ");
	scanf("%s", name);
	//判断是否有该联系人
	int ret = FindContact(pc, name);
	
	//有该联系人
	if (ret != -1)
	{
		int n = 0;
		do
		{
			menu1();
			Print(pc, ret);
			printf("请选择修改内容:> ");
			scanf("%d", &n);
			//修改
			switch (n)
			{
			case 1:
				ModName(pc,ret);
				break;
			case 2:
				ModAge(pc, ret);
				break;
			case 3:
				ModSex(pc, ret);
				break;
			case 4:
				ModTele(pc, ret);
				break;
			case 5:
				ModAddr(pc, ret);
				break;
			case 6:
				ModAll(pc, ret);
				break;
			case 0:
				printf("修改结束!\n");
				Sleep(2000);
				system("cls");
				break;
			default:
				printf("选择数非法!\n");
				Sleep(2000);
				system("cls");
				break;
			}

		} while (n);
	}
	else
	{
		printf("没有此联系人!\n");
		Sleep(2000);
		system("cls");
	}
}

//排序菜单
void menu2()
{
	system("cls");
	printf("**********************************\n");
	printf("***** 1. name    2. age **********\n");
	printf("**********************************\n");
}

//名字比较函数
int cmp_name(const void* str1, const void* str2)
{
	return strcmp(((PeoInfo*)str1)->name, ((PeoInfo*)str2)->name);
}

//名字排序
void SortName(Contact* pc)
{
	qsort(pc->data, pc->sz, sizeof(pc->data[0]), cmp_name);
}

//年龄比较函数
int cmp_age(const void* str1, const void* str2)
{

	return ((PeoInfo*)str1)->age - ((PeoInfo*)str2)->age;
}
//年龄排序
void SortAge(Contact* pc)
{
	qsort(pc->data, pc->sz, sizeof(pc->data[0]), cmp_age);
}

//排序联系人信息
void SortContact(Contact* pc)
{
	assert(pc);
	//判断为空
	if (pc->sz == 0)
	{
		printf("通讯录为空,无法排序!\n");
		Sleep(3000);
		system("cls");
		return;
	}


	menu2();
	int n = 0;
	printf("请选择排序方式:> ");
	scanf("%d", &n);
	//排序
	switch (n)
	{
	case 1:
		SortName(pc);
		system("cls");
		printf("排序成功!\n");
		break;
	case 2:
		SortAge(pc);
		system("cls");
		printf("排序成功!\n");
		break;
	default:
		printf("选择数非法!\n");
		Sleep(3000);
		system("cls");
		break;
	}
}

teste.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");
}

void test()
{
	int input = 0;
	Contact con;
	InitContact(&con);
	do
	{
		menu();
		printf("请选择操作数:> ");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			AddContact(&con);
			system("cls");
			break;
		case 2:
			DelContact(&con);
			system("cls"); 
			break;
		case 3:
			system("cls");
			Search(&con);
			break;
		case 4:
			ModContact(&con);
			break;
		case 5:
			system("cls");
			ShowContact(&con);
			break;
		case 6:
			SortContact(&con);
			break;
		case 0:
			printf("退出成功!\n");
			break;
		default:
			printf("选择数非法!\n");
			break;
		}

	} while (input);
}

int main()
{
	test();
	return 0;
}

OK, é isso para este compartilhamento! Bons irmãos, até a próxima!

Acho que você gosta

Origin blog.csdn.net/m0_75256358/article/details/132369058
Recomendado
Clasificación