動態記憶體開闢實現通訊錄

辰末之星發表於2024-12-02

除錯的主函式
test.h

#define  _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include "contant.h"
//#include "contant.c"

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   -1.enpty   **\n");
	printf("******************************\n");
}
enum Option
{
	EXIT = 0,
	ADD,
	DEL,
	SEARCH,
	MODIFY,
	SORT,
	PRINT,
	ENPTY=-1,

};
int main()
{	
	int input = -1;
	/*struct PeoInfo data[MAX_DATA];*/
	Contact Con;
	InitContact(&Con);
	do
	{
		menu();
		printf("請輸入一個值:> >");
		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:
				SaveContact(&Con);//儲存資料
				DestoryContact(&Con);
				printf("退出!\n");
				break;
			case ENPTY:
				EnptyContact(&Con);
				break;
			default:
				printf("非法格式!請重新選擇!\n");
				break;

		}
	} while (input);
	return 0;
}
`






宣告的標頭檔案

pragma once

include <stdio.h>

include <string.h>

include <stdlib.h>

define MAX_NAME 20

define MAX_SEX 10

define MAX_TELE 12

define MAX_ADDR 20

define MAX_DATA 1000

define DEFAULT_SZ 3

define INC_SZ 2

typedef struct PeoInfo
{
char name[MAX_NAME];
int age;
char sex[MAX_SEX];
char tele[MAX_TELE];
char addr[MAX_ADDR];
}PeoInfo;
//靜態增長版本
//typedef struct Contant
//{
// PeoInfo data[MAX_DATA];
// int sz;
//}Contact;
typedef struct Contant//定義通訊錄
{
PeoInfo* data;
int sz;
int capacity;
}Contact;
void InitContact(Contact* pc);
void AddContact(Contact* pc);
void PrintContact(const Contact pc);
void DelContact(Contact pc);
void SearchContact(Contact
pc);
void ModifyContact(Contact
pc);
void SortContact(Contact* pc);
void DestoryContact(Contact* pc);
void SaveContact(Contact* pc);
void LoadContact(Contact* pc);//載入檔案
void CheckCapacity(Contact* pc);//增容函式
void EnptyContact(Contact* pc);//清空通訊錄
`

功能函式實現

#define  _CRT_SECURE_NO_WARNINGS 1
#include "contant.h"
static int FindByName(Contact* pc,char name[])//查詢
{
	int i = 0;
	for (i = 0; i < pc->sz; i++)
	{
		if (strcmp(pc->data[i].name, name) == 0)
		{
			return i;
		}
	}
	return -1;
}
static int IsAdd(Contact*pc, char name[])//判斷姓名是否重複
{

	int pos= FindByName(pc, name);
	if (pos != -1)
	{
		printf("該姓名在通訊錄中已存在\n");
		printf("請重新命名:> ");
		return -1;
	}
	return 1;
}
//void InitContact(Contact* pc)//初始化通訊錄//靜態版本
//{
//	pc->sz = 0;
//	memset(pc->data, 0, sizeof(pc->data));
//}
void LoadContact(Contact* pc);
void InitContact(Contact* pc)//初始化通訊錄//動態版本
{
	pc->data = (PeoInfo*)malloc(DEFAULT_SZ * sizeof(PeoInfo));
	if (pc->data == NULL)
	{
		perror("InitContact");
		return;
	}
	pc->sz = 0;
	pc->capacity = DEFAULT_SZ;
	//載入檔案
	LoadContact(pc);
}
//void AddContact(Contact* pc)//新增聯絡人//靜態版本
//{
//	if (pc->sz >= MAX_DATA)
//	{
//		printf("通訊錄已存滿!\n");
//		return;
//	}
//
//	printf("請輸入姓名:> ");
//	while (1)
//	{
//		scanf("%s", (pc->data[pc->sz].name));
//		int Is = IsAdd(pc, (pc->data[pc->sz].name));
//		if (Is == 1)
//		{
//			break;
//		}
//	}
//	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));
//	printf("\n");
//	pc->sz++;
//	printf("存入成功!\n");
//
//}
void CheckCapacity(Contact* pc)
{
	if (pc->sz ==pc->capacity)
	{
		PeoInfo* ptr = realloc(pc->data, (pc->capacity + INC_SZ) * sizeof(PeoInfo));
		if (ptr != NULL)
		{
			pc->data = ptr;
			pc->capacity += INC_SZ;
			printf("增容成功!\n");
		}
		else
		{
			perror("AddContact");
			printf("增容失敗!\n");
			return;
		}
	}
}
void AddContact(Contact* pc)//新增聯絡人//動態版本
{
	CheckCapacity(pc);
	/*if (pc->sz ==pc->capacity)
	{
		PeoInfo* ptr = realloc(pc->data, (pc->capacity + INC_SZ) * sizeof(PeoInfo));
		if (ptr != NULL)
		{
			pc->data = ptr;
			pc->capacity += INC_SZ;
			printf("增容成功!\n");
		}
		else
		{
			perror("AddContact");
			printf("增容失敗!\n");
			return;
		}
	}*/

	printf("請輸入姓名:> ");
	while (1)
	{
		scanf("%s", (pc->data[pc->sz].name));
		int Is = IsAdd(pc, (pc->data[pc->sz].name));
		if (Is == 1)
		{
			break;
		}
	}
	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));
	printf("\n");
	pc->sz++;
	printf("存入成功!\n");

}
void PrintContact(const Contact* pc)//展示聯絡人
{
	printf("共%d位聯絡人\n", (pc->sz));
	printf("      %-5s\t %-5s\t %-3s\t %-12s\t %-20s\t\n", "姓名", "年齡", "性別", "電話", "地址");
	int i = 0;
	for (i = 0; i < pc->sz; i++)
	{
		printf("%4d)  %-5s\t %-5d\t %-3s\t %-12s\t %-20s\t\n",i+1, pc->data[i].name,
			pc->data[i].age,
			pc->data[i].sex,
			pc->data[i].tele,
			pc->data[i].addr);
		
	}
	
}

//void DelContact(Contact* pc)//刪除聯絡人//靜態版本
//{
//	char name[MAX_NAME] = { 0 };
//	if (pc->sz == 0)
//	{
//		printf("通訊錄為空!\n");
//		return;
//	}
//	printf("請輸入要刪除的名字:> ");
//	scanf("%s", name);
//	int pos = FindByName(pc, name);
//	if (pos == -1)
//	{
//		printf("無法找到對應姓名\n");
//		return;
//	}
//	//刪除
//	/*printf("確認要刪除該聯絡")*/
//	int i = 0;
//	for (i = pos; i <= (pc->sz - 1); i++)
//	{
//		pc->data[i] = pc->data[i + 1];
//	}
//	pc->sz--;
//	printf("\n");
//	printf("刪除成功!\n");
//	
//}
void DelContact(Contact* pc)//刪除聯絡人//動態版本
{
	char name[MAX_NAME] = { 0 };
	if (pc->sz == 0)
	{
		printf("通訊錄為空!\n");
		return;
	}
	printf("請輸入要刪除的名字:> ");
	scanf("%s", name);
	int pos = FindByName(pc, name);
	if (pos == -1)
	{
		printf("無法找到對應姓名\n");
		return;
	}
	//刪除
	/*printf("確認要刪除該聯絡")*/
	int i = 0;
	for (i = pos; i <= (pc->sz - 1); i++)
	{
		pc->data[i] = pc->data[i + 1];
	}
	pc->sz--;
	printf("\n");
	printf("刪除成功!\n");
	if ((pc->capacity - pc->sz) == INC_SZ&&pc->capacity>=DEFAULT_SZ)
	{
		PeoInfo* ptr = realloc(pc->data, (pc->capacity - INC_SZ) * sizeof(PeoInfo));
		if (ptr != NULL)
		{
			pc->data = ptr;
			pc->capacity -= INC_SZ;
			printf("減容成功!\n");
		}
		else
		{
			perror("AddContact");
			printf("減容失敗!\n");
			return;
		}

	}
}
void SearchContact(Contact* pc)
{
	char name[MAX_NAME] = { 0 };
	if (pc->sz == 0)
	{
		printf("通訊錄為空!\n");
		return;
	}
	printf("請輸入要查詢的名字:> ");
	scanf("%s", name);
	int pos = FindByName(pc, name);
	if (pos == -1)
	{
		printf("無法找到對應姓名\n");
		return;
	}
	printf("      %-5s\t %-5s\t %-3s\t %-12s\t %-20s\t\n", "姓名", "年齡", "性別", "電話", "地址");
	printf("%4d)  %-5s\t %-5d\t %-3s\t %-12s\t %-20s\t\n",pos+1, pc->data[pos].name,
		pc->data[pos].age,
		pc->data[pos].sex,
		pc->data[pos].tele,
		pc->data[pos].addr);
	printf("\n");
	printf("查詢成功!\n");
}
void ModifyContact(Contact* pc)
{
	char name[MAX_NAME] = { 0 };
	if (pc->sz == 0)
	{
		printf("通訊錄為空!\n");
		return;
	}
	printf("請輸入要修改的名字:> ");
	scanf("%s", name);
	int pos = FindByName(pc, name);
	if (pos == -1)
	{
		printf("無法找到對應姓名\n");
		return;
	}
	int x = 0;
	while (x==0)
	{
		printf("請開始修改!\n");
		printf("請輸入姓名:> ");
		scanf("%s", (pc->data[pos].name));
		int i = 0;
		for (i = 0; i < pc->sz; i++)
		{
			if (i == pos)
			{
				;
			}
			else if (strcmp(pc->data[i].name, pc->data[pos].name) == 0)
			{
				printf("重複姓名!");
				x = 0;
				break;
			}
			else
			{
				x = -1;
			}
			
		}
		/*printf("%d", x);*/
		if (x == -1)
		{
			break;
		}
	}
	
	printf("請輸入年齡:> ");
	scanf("%d", &(pc->data[pos].age));
	printf("請輸入性別:> ");
	scanf("%s", (pc->data[pos].sex));
	printf("請輸入電話:> ");
	scanf("%s", (pc->data[pos].tele));
	printf("請輸入地址:> ");
	scanf("%s", (pc->data[pos].addr));
	printf("\n");
	/*pc->sz++;*/
	printf("修改成功!\n");
}
void SortContact(Contact* pc)//排序
{
	char name[MAX_NAME] = { 0 };
	int pos2 = 0;
	printf("請選擇要排序的姓名");
	scanf("%s", name);
	int pos = FindByName(pc, name);
	if (pos == -1)
	{
		printf("無法找到對應姓名\n");
		return;
	}
	int pos3 = pos2 - 1;
	printf("pos= %d\n", pos + 1);
	printf("請選擇要修改到的位置(請輸入數字)!\n");
	/*printf("pos= %d\n", pos+1);*/
	scanf("%d", &pos3);//忘了寫&了
	pos2 = pos3 - 1;
	int i = 0;
	/*Contact tmp = { 0 };
	tmp.data[0] = (pc->data[pos]);*/
	/*if (pos2 >= 0 && pos2 <= pc->sz - 1)
	{
		printf("輸入錯誤\n");
	}
	for (i = pos; i >=pos2+1; i--)
	{
		pc->data[i] = pc->data[i - 1];
	}*/

	while(pos3<0 || pos3>(pc->sz) - 1 || pos3 == pos)
	{
		printf("輸入錯誤!\n");
		printf("pos= %d\n", pos + 1);
		printf("請重新選擇要修改到的位置(請輸入數字)!\n");
		/*printf("pos= %d\n", pos+1);*/
		scanf("%d", &pos3);
		pos2 = pos3 - 1;
	}
	PeoInfo data2[1] = { 0 };
	data2[0] = pc->data[pos];

	if (pos2 > pos)
	{
		for (i = pos; i <= pos2 ; i++)
		{
			pc->data[i] = pc->data[i + 1];
		}
		pc->data[pos2] = data2[0];
	}
	if (pos2 < pos)
	{
		for (i = pos; i >= pos2; i--)
		{
			pc->data[i] = pc->data[i - 1];
		}
		pc->data[pos2] = data2[0];
	}
	/*pc->data[pos2] = tmp.data[0];*/
	printf("\n");
	printf("修改排序完成!\n");
}
void DestoryContact(Contact* pc)//清除記憶體
{
	free(pc->data);
	pc->data = NULL;
	pc->sz = 0;
	pc->capacity = 0;
	
}
void SaveContact(Contact* pc)//儲存資料
{
	FILE* pf = fopen("contact.dat", "w");
	if (pf == NULL)
	{
		perror("fopen");
		return;
	}
	int i =0 ;
	for (i = 0; i < pc->sz; i++)
	{
		fwrite(pc->data + i, sizeof(PeoInfo), 1, pf);
	}
	//關閉檔案
	fclose(pf);
	pf = NULL;
	printf("儲存成功!");
}
void LoadContact(Contact* pc)
{
	FILE* pf = fopen("contact.dat", "r");
	if (pf ==NULL )
	{
		perror("fopen");
		return;
	}
	//讀取資料
	PeoInfo tmp = { 0 };
	while (fread(&tmp, sizeof(PeoInfo), 1, pf))//先將資料存入tmp中,再轉存到data中
	{
		CheckCapacity(pc);
		pc->data[pc->sz] = tmp;
		pc->sz++;
	}
	//關閉檔案
	fclose(pf);
	pf = NULL;
	printf("載入完成!\n");

}
void EnptyContact(Contact* pc)//清空通訊錄
{
	FILE* pf = fopen("contact.dat", "w");//利用w開啟即清空的特點清空通訊錄
	if (pf == NULL)
	{
		perror("fopen");
		return;
	}
	pc->sz = 0;
	pc->capacity = DEFAULT_SZ;
	fclose(pf);
	pf = NULL;
	
	printf("清空完成!\n");
}
`
ending.

相關文章