[Advanced C Language] Adressbuch (Vollversion)

1. Grundgerüst und Funktionen

Fügen Sie hier eine Bildbeschreibung ein

Vorbereitungsarbeit:
1. Untermodulentwicklung
 1.test.c, Implementierung der Testverknüpfung des Moduls
 2.contact.c, Implementierung der Funktion der Funktion
 3.contact.h, Implementierung der Benennung der Funktion und Verwendung von Die Struktur.
Das Folgende konzentriert sich auf die Implementierung der Funktion. Zu Beginn der Funktion wird eine Header-Datei bereitgestellt, um die Lesbarkeit dieses Artikels zu verbessern.

2. Details der Header-Datei

#include<stdio.h>//printf,scanf,perror
#include<stdlib.h>//system,malloc,realloc
#include<string.h>//strcmp
//对开辟的大小,方便之后的统一修改。
enum SIZE
{
    
    
	NAME_SIZE=10,
	SEX_SIZE=5,
	TELE_SIZE=15,
	ADDRE_SIZE=20,
	DEFAULT_SIZE=2,
	ADD_SIZE=2
};
//功能的选项数字赋予一定的意义
enum function
{
    
    
	ADD=1,
	DEL,
	FIND,
	MODIFY,
	PRINT,
	SORT,
	EXIT
};
//联系人信息
typedef struct people
{
    
    
	char name[NAME_SIZE];
	int age;
	char sex[SEX_SIZE];
	char tele[TELE_SIZE];
	char addre[ADD_SIZE];
}peo;
//通讯录信息
typedef struct Contact
{
    
    
	int count;//联系人个数
	int capacity;//当前最大容量
	peo CON[];//柔性数组利用内存池的概念,使内存管理更加高效,并且free只要一次,更方便。
}contact;

//菜单
void menu();
//初始化通讯录
void Init_contact(contact** p);//要修改一级指针所以要传一级指针的地址用二级指针来接收
//添加联系人信息
void Add_Contact(contact** p);//同理
//打印通讯录
void Print_Contact(contact* p);
//删除联系人信息
void Del_Contact(contact* p);
//查找联系人信息
void Find_Contact(contact* p);
//修改联系人信息
void Modify_Contact(contact* p);
//释放已开辟的内存空间
void Distory_Contact(contact** p);//同理
//按照名字进行排序通讯录
void Sort_Contact(contact* p);

3. Implementierung von Funktionen

1.Menü drucken

void menu()
{
    
    
	printf("******************************************\n");
	printf("******** 1.增加联系人 2.删除联系人 *******\n");
	printf("******** 3.查找联系人 4.修改联系人 *******\n");
	printf("******** 5.打印联系人 6.排序联系人 *******\n");
	printf("******** 7.退出通讯录              *******\n");
	printf("******************************************\n");

}

Keine Parameter, kein Rückgabetyp (Sie können return schreiben;)

2. Adressbuch initialisieren

void Init_contact(contact** p)
{
    
    
	*p = (contact*)malloc(4*2 + sizeof(peo) * DEFAULT_SIZE);
	if (*p != NULL)
	{
    
    
		(*p)->count = 0;
		(*p)->capacity = DEFAULT_SIZE;
	}
	else
	{
    
    
		perror("Init_contact");
		return;
	}
}

1. Der hier zugewiesene Speicherplatz beträgt standardmäßig zwei Ganzzahlen + die Anzahl der Kontakte, die anfänglich gespeichert werden können (2)
2. Der Strukturzeiger kann nur auf den Zeiger der ersten Ebene zugreifen. Um den Zeiger der ersten Ebene zu ändern, müssen Sie den zweiten übergeben -Level-Zeiger auf die Funktion. Zeiger
3. Calloc kann hier ebenfalls verwendet werden, ist jedoch umständlicher und etwas weniger effizient als malloc.
4. Achten Sie darauf, die zurückgegebene Adresse zu überprüfen, indem Sie das Feld öffnen.

3. Fügen Sie Kontaktinformationen hinzu

void Add_Contact(contact** p)
{
    
    
	int judge = 0;
	//判断内存是否够
	if ((*p)->count== (*p)->capacity)
	{
    
    
		printf("通讯录已满,请确定是否要增容(1是0否):");
		scanf("%d", &judge);
		if (judge)
		{
    
    
			contact* ptr = (contact*)realloc(*p, 4 * 2 + sizeof(peo) *   ((*p)->capacity+ ADD_SIZE));
			if (ptr != NULL)
			{
    
    
				(*p) = ptr;
				(*p)->capacity += ADD_SIZE;
				printf("增容成功\n");
			}
			else
			{
    
    
				perror("Add_Contact");
				printf("增容失败\n");
				return;
			}
		}
		else
		{
    
    
			return;
		}

	}
    //输入信息部分
	printf("请输入姓名:");
	scanf("%s", (*p)->CON[(*p)->count].name);

	printf("请输入年龄:");
	scanf("%d", &(*p)->CON[(*p)->count].age);

	printf("请输入性别:");
	scanf("%s", (*p)->CON[(*p)->count].sex);

	printf("请输入电话:");
	scanf("%s", (*p)->CON[(*p)->count].tele);

	printf("请输入住址:");
	scanf("%s", (*p)->CON[(*p)->count].addre);
	printf("增加成功!\n");
	(*p)->count++;
}

1. Überprüfen Sie den Rückgabewert von realloc. Wenn er leer ist, melden Sie umgehend einen Fehler.
2. Addieren Sie nach Eingabe der Informationen 1 zur Anzahl der Kontakte.
3. Bestimmen Sie bei der Eingabe der Informationen den Typ des Mitglieds, auf das zugegriffen wird, um es zu bestimmen ob die Adresse hinzugefügt werden soll
. : Bei der Eingabe des Adress-Array-Namens und des Array-Namens ist der Effekt derselbe, da ihre Werte gleich sind, ihre Bedeutungen jedoch unterschiedlich sind.

4.Kontaktinformationen ausdrucken

void Print_Contact(contact* p)
{
    
    
	if (p->count == 0)
	{
    
    
		printf("通讯录为空!\n");
		return;
	}
	printf("%-5s\t%3s\t%-3s\t%-12s\t%-20s\t\n", "姓名", 
												"年龄", 
												"性别", 
												"电话", 
												"住址");
	int i = 0;
	for (i = 0; i < p->count; i++)
	{
    
    
		printf("%-5s\t%3d\t%-3s\t%-12s\t%-20s\t\n", p->CON[i].name, 
													p->CON[i].age, 
													p->CON[i].sex, 
													p->CON[i].tele, 
													p->CON[i].addre);
	}
}

1. Wenn das Adressbuch keine Informationen enthält, sollten Sie rechtzeitig daran erinnert werden.
2. Achten Sie auf die Beziehung zwischen dem Index und der Anzahl der Kontaktinformationen.
3. Wenn der gedruckte Inhalt zu lang ist, wird empfohlen, die Zeile umzubrechen, um die Lesbarkeit des Codes zu verbessern.
4. Beim Drucken müssen Sie das Druckformat ausrichten und festlegen, damit der gedruckte Inhalt einfacher und schöner wird.

5. Finden Sie einen Namen

const int Find_By_name(contact* p,char*arr)
{
    
    
	int i = 0;
	for (i = 0; i < p->count; i++)
	{
    
    
		if (strcmp(p->CON[i].name, arr) == 0)
		{
    
    
			return i;
		}
	}
	return -1;
}

1. Da diese Funktion nur das Modul bedient, das die Funktion implementiert, wird const hinzugefügt.
2. strcmp vergleicht zwei Zeichenfolgen und gibt 0 zurück, wenn sie gleich sind.
3. Wenn keine Zeichenfolge vorhanden ist, wird -1 zurückgegeben. Wenn gefunden, wird zurückgegeben Sein Index ist
4. Diese Funktion wird verwendet, um Kontakte zu finden, Kontakte zu ändern und Kontakte zu löschen.

6. Kontaktinformationen löschen

void Del_Contact(contact* p)
{
    
    
	char name[20] = {
    
     0 };
	printf("请输入要删除的联系人:");
	scanf("%s", name);
	int ret = Find_By_name(p, name);
	if (ret!=-1)
	{
    
    
		int i = 0;
		for (i = ret; i < p->count-1; i++)
		{
    
    
			p->CON[ret] = p->CON[ret + 1];
		}
		p->count--;
		printf("已删除\n");
	}
	else
	{
    
    
		printf("查无此人\n");
	}
}

1. Die Idee des Löschens besteht darin, das letzte Element zu überschreiben. Wenn Sie es hinzufügen, nachdem die Anzahl der Kontakte verringert wurde, wird es überschrieben.
2. Achten Sie hier auf den Bereich von i. Durch die Kombination des folgenden Codes können wir sehen, dass das Problem auftreten kann, dass das Array außerhalb der Grenzen liegt. Subtrahieren Sie daher 1. 3. Die Mitglieder des Strukturarrays können das vorherige
Mitglied direkt überschreiben. Dies entspricht den Eigenschaften des Arrays.

7. Kontakte finden

void Find_Contact(contact* p)
{
    
    
	char name[20] = {
    
     0 };
	printf("请输入要查找的联系人:");
	scanf("%s", name);
	int ret = Find_By_name(p, name);
	if (ret != -1)
	{
    
    
		printf("%-5s\t%3s\t%-3s\t%-12s\t%-20s\t\n", "姓名", 
													"年龄", 
													"性别", 
													"电话", 
													"住址");
		printf("%-5s\t%3d\t%-3s\t%-12s\t%-20s\t\n", p->CON[ret].name,
													p->CON[ret].age, 
			                                        p->CON[ret].sex,
			                                        p->CON[ret].tele, 
													p->CON[ret].addre);
	}
	else
	{
    
    
		printf("查无此人\n");
	}
}

8. Ändern Sie die Kontaktinformationen

void Modify_Contact(contact* p)
{
    
    
	char name[20] = {
    
     0 };
	printf("请输入要修改的联系人:");
	scanf("%s", name);
	int ret = Find_By_name(p, name);
	if (ret != -1)
	{
    
    
		printf("请输入姓名:");
		scanf("%s", p->CON[ret].name);

		printf("请输入年龄:");
		scanf("%d", &p->CON[ret].age);

		printf("请输入性别:");
		scanf("%s", p->CON[ret].sex);

		printf("请输入电话:");
		scanf("%s", p->CON[ret].tele);

		printf("请输入住址:");
		scanf("%s", p->CON[ret].addre);
		printf("修改成功!\n");
	}
	else
	{
    
    
		printf("查无此人\n");
	}
}

9. Kontakte sortieren (nach Namen)

int my_cmp(const void* e1, const void* e2)
{
    
    
	return strcmp(((peo*)e1)->name, ((peo*)e2)->name);
}
void Sort_Contact(contact* p)
{
    
    
	qsort(p->CON, p->count, sizeof(peo), my_cmp);
	printf("排序成功!\n");
}

1. Sie müssen eine Vergleichsfunktion für die schnelle Sortierung schreiben. Da es sich um einen Zeichenfolgenvergleich handelt, müssen Sie die Zeichenfolgenvergleichsfunktion verwenden. 2. Achten Sie
auf die Parameter der schnellen Sortierung – das sortierte Array, die Anzahl der Sortierungen usw Größe der Elemente und die Vergleichsfunktion.

4. Zusammenfassung

1.Test.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"contact.h"
int main()
{
    
    
	contact *con =NULL;
	Init_contact(&con);
	int input = 0;
	do
	{
    
    
		menu();
		printf("请输入:");
		scanf("%d", &input);
		switch (input)
		{
    
    
		case ADD:
			system("cls");
			Add_Contact(&con);
			break;
		case DEL:
			system("cls");
			Del_Contact(con);
			break;
		case FIND:
			system("cls");
			Find_Contact(con);
			break;
		case MODIFY:
			system("cls");
			Modify_Contact(con);
			break;
		case PRINT:
			system("cls");
			Print_Contact(con);
			break;
		case SORT:
			system("cls");
			Sort_Contact(con);
			break;
		case EXIT:
			system("cls");
			Distory_Contact(&con);
			printf("退出成功\n");
			break;
		default:
			printf("输入错误\n");
			break;
		}

	} while (input!=EXIT);

	return 0;
}

2.Kontakt.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"contact.h"
void menu()
{
    
    
	printf("******************************************\n");
	printf("******** 1.增加联系人 2.删除联系人 *******\n");
	printf("******** 3.查找联系人 4.修改联系人 *******\n");
	printf("******** 5.打印联系人 6.排序联系人 *******\n");
	printf("******** 7.退出通讯录              *******\n");
	printf("******************************************\n");

}
void Init_contact(contact** p)
{
    
    
	*p = malloc(4*2 + sizeof(peo) * DEFAULT_SIZE);
	if (*p != NULL)
	{
    
    
		(*p)->count = 0;
		(*p)->capacity = DEFAULT_SIZE;
	}
	else
	{
    
    
		perror("Init_contact");
		return;
	}
}

//const void Think_Capacity(contact** p)
//{
    
    
//
//	if ((*p)->count == (*p)->capacity)
//	{
    
    
//		contact* ptr = (contact*)realloc(*p, 8 + sizeof(peo) * ((*p)->capacity + ADD_SIZE));
//		if (ptr != NULL)
//		{
    
    
//			(*p) = ptr;
//			(*p)->capacity += ADD_SIZE;
//			printf("增容成功\n");
//		}
//		else
//		{
    
    
//			perror("Add_Contact");
//			printf("增容失败\n");
//			return;
//		}
//	}
//
//}

//void Load_Contact(contact** p)
//{
    
    
//	FILE* pf = fopen("contact.txt", "rb");
//	if (NULL == pf)
//	{
    
    
//		perror("Load_Contact");
//	}
//	else
//	{
    
    
//		peo tmp = { 0 };
//		while (fread(&tmp, sizeof(peo), 1, pf))
//		{
    
    
//			Think_Capacity(p);
//			(*p)->CON[(*p)->count] = tmp;
//			(*p)->count++;
//		}
//	}
//	fclose(pf);
//	pf = NULL;
//}

void Add_Contact(contact** p)
{
    
    
	int judge = 0;
	if ((*p)->count== (*p)->capacity)
	{
    
    
		printf("通讯录已满,请确定是否要增容(1是0否):");
		scanf("%d", &judge);
		if (judge)
		{
    
    
			contact* ptr = (contact*)realloc(*p, 4 * 2 + sizeof(peo) * ((*p)->capacity + ADD_SIZE));
			if (ptr != NULL)
			{
    
    
				(*p) = ptr;
				(*p)->capacity += ADD_SIZE;
				printf("增容成功\n");
			}
			else
			{
    
    
				perror("Add_Contact");
				printf("增容失败\n");
				return;
			}
		}
		else
		{
    
    
			return;
		}

	}

	printf("请输入姓名:");
	scanf("%s", (*p)->CON[(*p)->count].name);

	printf("请输入年龄:");
	scanf("%d", &(*p)->CON[(*p)->count].age);

	printf("请输入性别:");
	scanf("%s", (*p)->CON[(*p)->count].sex);

	printf("请输入电话:");
	scanf("%s", (*p)->CON[(*p)->count].tele);

	printf("请输入住址:");
	scanf("%s", (*p)->CON[(*p)->count].addre);
	printf("增加成功!\n");
	(*p)->count++;
}

void Print_Contact(contact* p)
{
    
    
	if (p->count == 0)
	{
    
    
		printf("通讯录为空!\n");
		return;
	}
	printf("%-5s\t%3s\t%-3s\t%-12s\t%-20s\t\n", "姓名", "年龄", "性别", "电话", "住址");
	int i = 0;
	for (i = 0; i < p->count; i++)
	{
    
    
		printf("%-5s\t%3d\t%-3s\t%-12s\t%-20s\t\n", p->CON[i].name, 
													p->CON[i].age, 
													p->CON[i].sex, 
													p->CON[i].tele, 
													p->CON[i].addre);
	}
}
const int Find_By_name(contact* p,char*arr)
{
    
    
	int i = 0;
	for (i = 0; i < p->count; i++)
	{
    
    
		if (strcmp(p->CON[i].name, arr) == 0)
		{
    
    
			return i;
		}
	}
	return -1;
}
void Del_Contact(contact* p)
{
    
    
	char name[20] = {
    
     0 };
	printf("请输入要删除的联系人:");
	scanf("%s", name);
	int ret = Find_By_name(p, name);
	if (ret!=-1)
	{
    
    
		int i = 0;
		for (i = ret; i < p->count-1; i++)
		{
    
    
			p->CON[ret] = p->CON[ret + 1];
		}
		p->count--;
		printf("已删除\n");
	}
	else
	{
    
    
		printf("查无此人\n");
	}
}
void Find_Contact(contact* p)
{
    
    
	char name[20] = {
    
     0 };
	printf("请输入要查找的联系人:");
	scanf("%s", name);
	int ret = Find_By_name(p, name);
	if (ret != -1)
	{
    
    
		printf("%-5s\t%3s\t%-3s\t%-12s\t%-20s\t\n", "姓名", "年龄", "性别", "电话", "住址");
		printf("%-5s\t%3d\t%-3s\t%-12s\t%-20s\t\n", p->CON[ret].name, p->CON[ret].age, 
			                                        p->CON[ret].sex, p->CON[ret].tele, 
													p->CON[ret].addre);
	}
	else
	{
    
    
		printf("查无此人\n");
	}
}
void Modify_Contact(contact* p)
{
    
    
	char name[20] = {
    
     0 };
	printf("请输入要修改的联系人:");
	scanf("%s", name);
	int ret = Find_By_name(p, name);
	if (ret != -1)
	{
    
    
		printf("请输入姓名:");
		scanf("%s", p->CON[ret].name);

		printf("请输入年龄:");
		scanf("%d", &p->CON[ret].age);

		printf("请输入性别:");
		scanf("%s", p->CON[ret].sex);

		printf("请输入电话:");
		scanf("%s", p->CON[ret].tele);

		printf("请输入住址:");
		scanf("%s", p->CON[ret].addre);
		printf("修改成功!\n");
	}
	else
	{
    
    
		printf("查无此人\n");
	}


}
//void Save_Contact(contact* p)
//{
    
    
//	FILE* pf = fopen("contact.txt", "wb");
//	if (NULL == pf)
//	{
    
    
//		perror("Save_Contact:pf");
//	}
//	else
//	{
    
    
//		int i = 0;
//		for (i = 0; i < p->count; i++)
//		{
    
    
//			fwrite(p->CON + i, sizeof(peo), 1, pf);
//		}
//	}
//	printf("保存成功!\n");
//	fclose(pf);
//	pf = NULL;
//
//}

void Distory_Contact(contact** p)
{
    
    
	free(*p);
	*p = NULL;
}



int my_cmp(const void* e1, const void* e2)
{
    
    
	return strcmp(((peo*)e1)->name, ((peo*)e2)->name);
}
void Sort_Contact(contact* p)
{
    
    
	qsort(p->CON, p->count, sizeof(peo), my_cmp);
	printf("排序成功!\n");
}

3.Kontakt.h

#include<stdio.h>//printf,scanf,perror
#include<stdlib.h>//system,malloc,realloc
#include<string.h>//strcmp
//对开辟的大小,方便之后的统一修改。
enum SIZE
{
    
    
	NAME_SIZE=10,
	SEX_SIZE=5,
	TELE_SIZE=15,
	ADDRE_SIZE=20,
	DEFAULT_SIZE=2,
	ADD_SIZE=2
};
//功能的选项数字赋予一定的意义
enum function
{
    
    
	ADD=1,
	DEL,
	FIND,
	MODIFY,
	PRINT,
	SORT,
	EXIT
};
//联系人信息
typedef struct people
{
    
    
	char name[NAME_SIZE];
	int age;
	char sex[SEX_SIZE];
	char tele[TELE_SIZE];
	char addre[ADD_SIZE];
}peo;
//通讯录信息
typedef struct Contact
{
    
    
	int count;//联系人个数
	int capacity;//当前最大容量
	peo CON[];//柔性数组利用内存池的概念,使内存管理更加高效,并且free只要一次,更方便。
}contact;

//菜单
void menu();
//初始化通讯录
void Init_contact(contact** p);//要修改一级指针所以要传一级指针的地址用二级指针来接收
//添加联系人信息
void Add_Contact(contact** p);//同理
//打印通讯录
void Print_Contact(contact* p);
//删除联系人信息
void Del_Contact(contact* p);
//查找联系人信息
void Find_Contact(contact* p);
//修改联系人信息
void Modify_Contact(contact* p);
//释放已开辟的内存空间
void Distory_Contact(contact** p);//同理
//按照名字进行排序通讯录
void Sort_Contact(contact* p);
//保存通讯录信息
//void Save_Contact(contact* p);
//加载通讯录信息
//void Load_Contact(contact* p);

5. Für Dateioperationen erforderliche Funktionen

1. Kapazität prüfen

const void Think_Capacity(contact** p)
{
    
    

	if ((*p)->count == (*p)->capacity)
	{
    
    
		contact* ptr = (contact*)realloc(*p, 8 + sizeof(peo) * ((*p)->capacity + ADD_SIZE));
		if (ptr != NULL)
		{
    
    
			(*p) = ptr;
			(*p)->capacity += ADD_SIZE;
			printf("增容成功\n");
		}
		else
		{
    
    
			perror("Add_Contact");
			printf("增容失败\n");
			return;
		}
	}

}

2. Fügen Sie Kontaktinformationen hinzu

void Load_Contact(contact** p)
{
    
    
	FILE* pf = fopen("contact.txt", "rb");
	if (NULL == pf)
	{
    
    
		perror("Load_Contact");
	}
	else
	{
    
    
		peo tmp = {
    
     0 };
		while (fread(&tmp, sizeof(peo), 1, pf))
		{
    
    
			Think_Capacity(p);
			(*p)->CON[(*p)->count] = tmp;
			(*p)->count++;
		}
	}
	fclose(pf);
	pf = NULL;
}

3. Kontaktinformationen speichern

void Save_Contact(contact* p)
{
    
    
	FILE* pf = fopen("contact.txt", "wb");
	if (NULL == pf)
	{
    
    
		perror("Save_Contact:pf");
	}
	else
	{
    
    
		int i = 0;
		for (i = 0; i < p->count; i++)
		{
    
    
			fwrite(p->CON + i, sizeof(peo), 1, pf);
		}
	}
	printf("保存成功!\n");
	fclose(pf);
	pf = NULL;

}

So erstellen Sie eine im aktuellen Projekt (gleicher Pfad wie die Quelldatei): contact.txt

Supongo que te gusta

Origin blog.csdn.net/Shun_Hua/article/details/128677214
Recomendado
Clasificación