Carnet d'adresses (réalisé en langage C pur)

Je crois que tout le monde a un carnet d'adresses. Aujourd'hui je vais vous emmener réaliser le carnet d'adresses le plus simple ci-dessous. A travers cet article, je crois que vous pourrez avoir une meilleure compréhension du langage C.

Pas grand chose à dire, mettons d'abord l'implémentation de la fonction

#define  _CRT_SECURE_NO_WARNINGS 1
#include "Contact.h"


int CheakCapacity(Contact* ps);

void LoadContact(Contact* ps)
{
	FILE* pf = fopen("Contact.dat", "rb");
	if (pf == NULL)
	{
		perror("LoadContact");
		return;
	}
	PeoInfo tmp = { 0 };
	while (fread(&tmp,sizeof(PeoInfo),1,pf))
	{
		CheakCapacity(ps);
		ps->date[ps->size] = tmp;
		ps->size++;
	}

	fclose(pf);
	pf = NULL;

	
}

void InitContact(Contact* ps)
{
	assert(ps);
	ps->date = NULL;
	ps->size = ps->capacity = 0;
	LoadContact(ps);
}

int CheakCapacity(Contact* ps)
{
	assert(ps);
	if (ps->capacity == ps->size)
	{
		int newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
		PeoInfo* tmp = (PeoInfo*)realloc(ps->date, newcapacity * sizeof(PeoInfo));
		if (tmp == NULL)
		{
			perror("CheakCapacity");
			return 0;
		}
		else
		{
			ps->date = tmp;
			ps->capacity = newcapacity;
			printf("增容成功\n");
			return 1;
		}
	}
	return 1;
}

void AddContact(Contact* ps)
{
	assert(ps);
	if (CheakCapacity(ps) == 0)
	{
		return;
	}

	printf("请输入增加的姓名:>");
	scanf("%s", ps->date[ps->size].name);
	printf("请输入增加的年龄:>");
	scanf("%d", &ps->date[ps->size].age);
	printf("请输入增加的性别:>");
	scanf("%s", ps->date[ps->size].sex);
	printf("请输入增加的电话:>");
	scanf("%s", ps->date[ps->size].tele);
	printf("请输入增加的地址:>");
	scanf("%s", ps->date[ps->size].addr);
	
	ps->size++;
	printf("增加成功\n");
}

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

	printf("%-10s\t%-4s\t%-5s\t%-12s\t%-30s\n", "名字", "年龄", "性别", "电话", "地址");

	for (int i =0; i<ps->size; i++)
	{
		printf("%-10s\t%-4d\t%-5s\t%-12s\t%-30s\n",
			ps->date[i].name,
			ps->date[i].age,
			ps->date[i].sex,
			ps->date[i].tele,
			ps->date[i].addr
			);
	}
}

int FindByName(const Contact* ps,char name[])
{
	int i = 0;
	for (i =0; i<ps->size; i++)
	{
		if (strcmp(ps->date[i].name,name)==0)
		{
			return i;
		}
	}
	return -1;
}

void DeleteContact(Contact* ps)
{
	assert(ps);
	if (ps->size == 0)
	{
		printf("通讯录为空,无法删除\n");
		return;
	}

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

	int ret = FindByName(ps, name);
	if (ret == -1)
	{
		printf("要删除的人不存在\n");
		return;
	}

	for (int i =ret; i<ps->size; i++)
	{
		ps->date[i] = ps->date[i + 1];
	}

	ps->size--;
	printf("删除成功\n");
}

void SearchContact(Contact* ps)
{
	assert(ps);
	char name[20] = { 0 };
	printf("请输入你要删除的姓名:>");
	scanf("%s", name);

	int pos = FindByName(ps, name);
	if (pos == -1)
	{
		printf("要查找的人不存在\n");
		return;
	}

	printf("%-10s\t%-4d\t%-5s\t%-12s\t%-30s\n",
		ps->date[pos].name,
		ps->date[pos].age,
		ps->date[pos].sex,
		ps->date[pos].tele,
		ps->date[pos].addr
	);
}

void ModifyContact(Contact* ps)
{
	assert(ps);
	char name[20] = { 0 };
	printf("请输入你要修改的姓名:>");
	scanf("%s", name);

	int pos = FindByName(ps, name);
	if (pos == -1)
	{
		printf("要修改的人不存在\n");
		return;
	}

	printf("请输入修改的姓名:>");
	scanf("%s", ps->date[pos].name);
	printf("请输入修改的年龄:>");
	scanf("%d", &ps->date[pos].age);
	printf("请输入修改的性别:>");
	scanf("%s", ps->date[pos].sex);
	printf("请输入修改的电话:>");
	scanf("%s", ps->date[pos].tele);
	printf("请输入修改的地址:>");
	scanf("%s", ps->date[pos].addr);
}

void SortContact(Contact* ps)
{
	int i = 0;
	int j = 0;
	for (i=0; i<ps->size-1; i++)
	{
		for (j =0; j<ps->size-1-i; j++)
		{
			if (strcmp(ps->date[j].name, ps->date[j+1].name) > 0)
			{
				PeoInfo tmp = ps->date[j];
				ps->date[j] = ps->date[j + 1];
				ps->date[j + 1] = tmp;
			}
		}
	}
	printf("排序成功\n");
}

void DestoryContact(Contact* ps)
{
	free(ps->date);
	ps->date = NULL;
	ps->capacity = ps->size = 0;
}

void SaveContact(Contact* ps)
{
	FILE* pf = fopen("Contact.dat", "wb");
	if (pf == NULL)
	{
		perror("SaveContact");
		return;
	}
	for (int i =0; i<ps->size; i++)
	{
		fwrite(ps->date+ i, sizeof(PeoInfo), 1, pf);
	}

	fclose(pf);
	pf = NULL;
}

#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.show    6.sort *************\n");
	printf("*********** 0.exit  ********* ************\n");

}

void Text()
{
	int input = 0;
	Contact con;
	InitContact(&con);
	do 
	{
		menu();
		printf("请输入你的选择:>");
		scanf("%d", &input);
		switch (input)
		{
		case ADD:
			AddContact(&con);
			break;
		case DEL:
			DeleteContact(&con);
			break;
		case SEARCH:
			SearchContact(&con);
			break;
		case MODIFY:
			ModifyContact(&con);
			break;
		case SHOW:
			ShowContact(&con);
			break;
		case SORT:
			SortContact(&con);
			break;
		case EXIT:
			SaveContact(&con);
			DestoryContact(&con);
			printf("退出通讯录成功\n");
			break;
		default:
			printf("你选择的有误,请重新输入\n");
			break;

		}
	} while (input);
}

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

 Ça vous fait peur de voir ça ? ? N'ayez pas peur, suivez mes idées, vous pouvez aussi le réaliser, je vous emmènerai réaliser chaque fonction pas à pas

  •  Nous voulons réaliser cette fonction. D'abord, regardons le code suivant. D'abord, nous devons choisir en premier. Ici, je choisis l'instruction do while. Pour réaliser cette fonction, nous utilisons la fonction menu pour imprimer le menu. En fait, c'est très simple, et j'utilise la fonction printf pour le réaliser.
void Text()
{
	int input = 0;
	Contact con;
	InitContact(&con);
	do 
	{
		menu();
		printf("请输入你的选择:>");
		scanf("%d", &input);
		switch (input)
		{
		case ADD:
			AddContact(&con);
			break;
		case DEL:
			DeleteContact(&con);
			break;
		case SEARCH:
			SearchContact(&con);
			break;
		case MODIFY:
			ModifyContact(&con);
			break;
		case SHOW:
			ShowContact(&con);
			break;
		case SORT:
			SortContact(&con);
			break;
		case EXIT:
			SaveContact(&con);
			DestoryContact(&con);
			printf("退出通讯录成功\n");
			break;
		default:
			printf("你选择的有误,请重新输入\n");
			break;

		}
	} while (input);
}

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

}

  • Implémentons directement les fonctions de base du carnet d'adresses. J'utilise d'abord struct pour définir les informations de base d'une personne, puis j'utilise struct pour contenir les informations de base de la personne, mais j'ajoute également la taille et la capacité. La taille est utilisée pour enregistrer le nombre de personnes stockées et la capacité est utilisée pour indiquer l'espace disponible.
    typedef struct PeoInfo
    {
    	char name[MAX_NAME];
    	int age;
    	char sex[MAX_SEX];
    	char tele[MAX_TELE];
    	char addr[MAX_ADDR];
    }PeoInfo;
    
    typedef struct Contact
    {
    	PeoInfo *date;
    	int size;
    	int capacity;
    }Contact;

  •  N'oubliez pas d'initialiser le carnet d'adresses lors de la première utilisation.Ici, j'ai mis l'espace pointé par ps->date à NULL, et initialisé la taille et la capacité à 0. Parce que nous voulons créer un carnet d'adresses dynamique, nous utilisons spécialement le pointeur de structure date pour concevoir.
  • Implémentons un carnet d'adresses. Imaginons d'abord un scénario. Si votre téléphone portable est éteint, les informations du carnet d'adresses existeront-elles toujours après le redémarrage, nous devons donc également implémenter une telle fonction.
  • J'ai utilisé les opérations sur les fichiers ici. J'ai d'abord créé la variable temporaire tmp de la structure, et j'ai utilisé fread pour l'exploiter. Si la valeur de retour de freaed n'est pas 0, nous copierons les données dans tmp.
  • while (fread(&tmp,sizeof(PeoInfo),1,pf))
    	{
    		CheakCapacity(ps);
    		ps->date[ps->size] = tmp;
    		ps->size++;
    	}

    Voici le code complet de cette fonction

  • void LoadContact(Contact* ps)
    {
    	FILE* pf = fopen("Contact.dat", "rb");
    	if (pf == NULL)
    	{
    		perror("LoadContact");
    		return;
    	}
    	PeoInfo tmp = { 0 };
    	while (fread(&tmp,sizeof(PeoInfo),1,pf))
    	{
    		CheakCapacity(ps);
    		ps->date[ps->size] = tmp;
    		ps->size++;
    	}
    
    	fclose(pf);
    	pf = NULL;
    
    	
    }
    
    void InitContact(Contact* ps)
    {
    	assert(ps);
    	ps->date = NULL;
    	ps->size = ps->capacity = 0;
    	LoadContact(ps);
    }

  •  Passons ensuite à la deuxième fonction, l'ajout d'informations sur les personnes. Lorsque nous ajoutons des informations au début, nous devons penser à étendre la capacité si l'espace est plein. Par conséquent, je juge s'il faut étendre la capacité au début, car la taille et la capacité sont toutes deux à 0 au début, donc la capacité doit être étendue depuis le début. Je malloce un espace, et s'il est plein, je l'étendrai deux fois. Enfin, la valeur de retour est utilisée pour juger si l'expansion est réussie.
int CheakCapacity(Contact* ps)
{
	assert(ps);
	if (ps->capacity == ps->size)
	{
		int newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
		PeoInfo* tmp = (PeoInfo*)realloc(ps->date, newcapacity * sizeof(PeoInfo));
		if (tmp == NULL)
		{
			perror("CheakCapacity");
			return 0;
		}
		else
		{
			ps->date = tmp;
			ps->capacity = newcapacity;
			printf("增容成功\n");
			return 1;
		}
	}
	return 1;
}
  • Ensuite, implémentez la fonction add, qui est en fait très simple. Notre taille initiale est 0, donc chaque fois que nous ajoutons une information, ps->size a besoin de ++, et ps->date pointe vers l'espace de l'information sur la personne. Après ps->date [ps->size], ajoutez les informations que nous voulons ajouter, et la fonction de notre fonction add est terminée.

void AddContact(Contact* ps)
{
	assert(ps);
	if (CheakCapacity(ps) == 0)
	{
		return;
	}

	printf("请输入增加的姓名:>");
	scanf("%s", ps->date[ps->size].name);
	printf("请输入增加的年龄:>");
	scanf("%d", &ps->date[ps->size].age);
	printf("请输入增加的性别:>");
	scanf("%s", ps->date[ps->size].sex);
	printf("请输入增加的电话:>");
	scanf("%s", ps->date[ps->size].tele);
	printf("请输入增加的地址:>");
	scanf("%s", ps->date[ps->size].addr);
	
	ps->size++;
	printf("增加成功\n");
}


  •  Pour la deuxième fonction de suppression, mon idée est de créer d'abord un tableau, puis d'utiliser le tableau pour comparer avec les noms du carnet d'adresses pour voir s'ils sont égaux. Puis retournez l'indice à supprimer
int FindByName(const Contact* ps,char name[])
{
	int i = 0;
	for (i =0; i<ps->size; i++)
	{
		if (strcmp(ps->date[i].name,name)==0)
		{
			return i;
		}
	}
	return -1;
}
  • La dernière opération à supprimer est de se déplacer de l'arrière vers l'avant, puis ps->size-- c'est tout.
void DeleteContact(Contact* ps)
{
	assert(ps);
	if (ps->size == 0)
	{
		printf("通讯录为空,无法删除\n");
		return;
	}

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

	int ret = FindByName(ps, name);
	if (ret == -1)
	{
		printf("要删除的人不存在\n");
		return;
	}

	for (int i =ret; i<ps->size; i++)
	{
		ps->date[i] = ps->date[i + 1];
	}

	ps->size--;
	printf("删除成功\n");
}


  •  L'implémentation de la troisième fonction de recherche est similaire à l'opération de suppression, mais nous sommes une fonction de recherche, donc nous imprimons finalement les informations que nous voulons trouver directement par printf. Ici, j'utilise également le multiplexage de la fonction FindByName.

void SearchContact(Contact* ps)
{
	assert(ps);
	char name[20] = { 0 };
	printf("请输入你要删除的姓名:>");
	scanf("%s", name);

	int pos = FindByName(ps, name);
	if (pos == -1)
	{
		printf("要查找的人不存在\n");
		return;
	}

	printf("%-10s\t%-4d\t%-5s\t%-12s\t%-30s\n",
		ps->date[pos].name,
		ps->date[pos].age,
		ps->date[pos].sex,
		ps->date[pos].tele,
		ps->date[pos].addr
	);
}


  •  La quatrième fonction de modification, car il faut aussi trouver l'indice à modifier, j'ai donc utilisé la réutilisation des fonctions, il suffit de ressaisir la valeur que l'on souhaite modifier dans l'indice à modifier.
void ModifyContact(Contact* ps)
{
	assert(ps);
	char name[20] = { 0 };
	printf("请输入你要修改的姓名:>");
	scanf("%s", name);

	int pos = FindByName(ps, name);
	if (pos == -1)
	{
		printf("要修改的人不存在\n");
		return;
	}

	printf("请输入修改的姓名:>");
	scanf("%s", ps->date[pos].name);
	printf("请输入修改的年龄:>");
	scanf("%d", &ps->date[pos].age);
	printf("请输入修改的性别:>");
	scanf("%s", ps->date[pos].sex);
	printf("请输入修改的电话:>");
	scanf("%s", ps->date[pos].tele);
	printf("请输入修改的地址:>");
	scanf("%s", ps->date[pos].addr);
}


 Avez-vous trouvé que la mise en œuvre de nombreuses fonctions est en fait similaire, alors n'ayez pas peur, puis regardez en arrière.

  •  La cinquième fonction : nous voulons afficher les informations, nous utilisons simplement la boucle for pour les parcourir une fois, mais nous utilisons l'alignement à gauche pour mieux paraître, et la longueur peut être réalisée selon vous. L'effet final est le suivant.

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

	printf("%-10s\t%-4s\t%-5s\t%-12s\t%-30s\n", "名字", "年龄", "性别", "电话", "地址");

	for (int i =0; i<ps->size; i++)
	{
		printf("%-10s\t%-4d\t%-5s\t%-12s\t%-30s\n",
			ps->date[i].name,
			ps->date[i].age,
			ps->date[i].sex,
			ps->date[i].tele,
			ps->date[i].addr
			);
	}
}


  •  La sixième fonction : Nous voulons trier la taille du nom. Ici, j'utilise directement le tri à bulles, qui permet de trier directement la taille du nom. C'est juste que la complexité temporelle ici est O(N^2), et l'efficacité est très faible.Il peut également être réalisé par un tri rapide, et l'efficacité peut être plus élevée
void SortContact(Contact* ps)
{
	int i = 0;
	int j = 0;
	for (i=0; i<ps->size-1; i++)
	{
		for (j =0; j<ps->size-1-i; j++)
		{
			if (strcmp(ps->date[j].name, ps->date[j+1].name) > 0)
			{
				PeoInfo tmp = ps->date[j];
				ps->date[j] = ps->date[j + 1];
				ps->date[j + 1] = tmp;
			}
		}
	}
	printf("排序成功\n");
}


  •  Parce que nous implémentons le carnet d'adresses dynamiquement, j'ai utilisé malloc.Quand je quitte enfin, j'ai aussi besoin de libérer l'espace ouvert.J'ai utilisé une fonction DestoryContact pour y parvenir.
  • void DestoryContact(Contact* ps)
    {
    	free(ps->date);
    	ps->date = NULL;
    	ps->capacity = ps->size = 0;
    }


  • La dernière fonction : Avez-vous déjà pensé à un tel problème, lorsque nous saisissons des informations, si nous quittons, les informations seront toujours enregistrées lorsque nous les ouvrirons la prochaine fois ? ? ? Après avoir appris, j'ai découvert que les opérations sur les fichiers pouvaient être utilisées pour y parvenir.
  • J'ai utilisé fopen pour ouvrir un fichier binaire Contact.dat, et utilisé la boucle for fwrite pour enregistrer les informations existantes dans le flux de fichiers (c'est-à-dire ce fichier), et parce qu'au début de l'initialisation, les informations du fichier doivent être enregistrées, afin que nous réalisions la préservation des informations.
void SaveContact(Contact* ps)
{
	FILE* pf = fopen("Contact.dat", "wb");
	if (pf == NULL)
	{
		perror("SaveContact");
		return;
	}
	for (int i =0; i<ps->size; i++)
	{
		fwrite(ps->date+ i, sizeof(PeoInfo), 1, pf);
	}

	fclose(pf);
	pf = NULL;
}

Je suppose que tu aimes

Origine blog.csdn.net/m0_72165281/article/details/131745871
conseillé
Classement