欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C語(yǔ)言實(shí)現(xiàn)一個(gè)文件版動(dòng)態(tài)通訊錄流程詳解

 更新時(shí)間:2023年01月29日 16:38:14   作者:平凡的小蘇  
這篇文章主要介紹了C語(yǔ)言實(shí)現(xiàn)一個(gè)文件版動(dòng)態(tài)通訊錄流程,希望大家能從這篇文章中收獲到許多,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)吧

通訊錄思維導(dǎo)圖

?

一、Contact.h

#include<stdio.h>
#include<assert.h>
#include<string.h>
#include<stdlib.h>
#define NAME_MAX 20
#define SEX_MAX 5
#define TELE_MAX 11
#define ADDR_MAX 30
#define INIT_CAPA 3
#define INC_CAPA 2
typedef struct PeoInfo
{
	char name[NAME_MAX];
	int age;
	char sex[SEX_MAX];
	char tele[TELE_MAX];
	char addr[ADDR_MAX];
}PeoInfo;
//動(dòng)態(tài)版本
typedef struct Contact
{
	PeoInfo* data;
	int sz;//表示通訊錄有多少個(gè)聯(lián)系人
	int capacity;//表示通訊錄的最大容量
}Contact;
//初始化通訊錄
void InitContact(Contact* pc);
//添加聯(lián)系人
void AddContact(Contact* pc);
//刪除聯(lián)系人
void DelContact(Contact* pc);
//顯示通訊錄
void ShowContact(const Contact* pc);
//查找聯(lián)系人
void SearchContact(Contact*pc);
//修改聯(lián)系人'
void ModifyContact(Contact*pc);
//通過(guò)名字排序聯(lián)系人
void ByNameSortContact(Contact* pc);
//銷(xiāo)毀聯(lián)系人
void DestroyContact(Contact* pc);
//保存聯(lián)系人到文本文件中
void SaveContact(Contact* pc);
//從文件中讀取聯(lián)系人的信息
void GetContact(Contact* pc);

這些是頭文件的包含,函數(shù)的聲明,以及#define定義的常量,為了以后修改方便

二、Contact.c

1.初始化通訊錄

void InitContact(Contact* pc)//初始化通訊錄
{
	assert(pc!=NULL);
	pc-> sz = 0;
	pc->capacity = INIT_CAPA;
	PeoInfo * ptr = (PeoInfo*)calloc(INIT_CAPA, sizeof(PeoInfo));
	if (ptr == NULL)
	{
		perror("InitContact");
		return;
	}
	pc->data = ptr;
	GetContact(pc);
}

初始化通訊錄的容量開(kāi)始為3,sz初始時(shí)為0,動(dòng)態(tài)開(kāi)辟的ptr開(kāi)辟成功在賦給data。

2.檢查容量是否滿

void check_capacity(Contact* pc)//檢查容量是否滿
{
	assert(pc);
	if (pc->capacity == pc->sz)
	{
		PeoInfo*ptr = (PeoInfo*)realloc(pc->data, (pc->capacity + 2) * sizeof(PeoInfo));
		if (ptr == NULL)
		{
			perror("check_capacity");
			return;
		}
		pc->data = ptr;
		pc->capacity += INC_CAPA;
		printf("增容成功\n");
	}
}

如果容量滿,則每次增容兩個(gè),如果想要增容更多,則修改define定義的常量就可以修改了。

realloc開(kāi)辟的時(shí)候有可能是用pc->data來(lái)往后擴(kuò)大增容,也有可能是用新的空間來(lái)開(kāi)辟,為了防止開(kāi)辟失敗,使原有的數(shù)據(jù)丟失,則先使用新的指針變量來(lái)接收動(dòng)態(tài)開(kāi)辟的空間,如果開(kāi)辟成功,再將它賦給data。

3.添加聯(lián)系人

void AddContact(Contact* pc)//添加聯(lián)系人
{
	assert(pc != NULL);
	check_capacity(pc);
	printf("請(qǐng)輸入姓名:\n");
	scanf("%s", pc->data[pc->sz].name);
	printf("請(qǐng)輸入年齡:\n");
	scanf("%d", &(pc->data[pc->sz].age));
	printf("請(qǐng)輸入性別:\n");
	scanf("%s", pc->data[pc->sz].sex);
	printf("請(qǐng)輸入號(hào)碼:\n");
	scanf("%s", pc->data[pc->sz].tele);
	printf("請(qǐng)輸入地址:\n");
	scanf("%s", pc->data[pc->sz].addr);
	printf("添加聯(lián)系人成功\n");
	pc->sz++;
}

添加聯(lián)系人前,需要先判斷是否需要增容

4.顯示聯(lián)系人

void ShowContact(const Contact* pc)//顯示聯(lián)系人
{
	assert(pc != NULL);
	printf("%-20s\t%-4s\t%-4s\t%-12s\t%-30s\n","姓名","年齡","性別","電話號(hào)碼","地址");
	for (int i = 0; i < pc->sz; i++)
	{
		printf("%-20s\t%-4d\t%-4s\t%-12s\t%-30s\n", pc->data[i].name,
			pc->data[i].age,
			pc->data[i].sex,
			pc->data[i].tele,
			pc->data[i].addr);
	}
}

5.查找聯(lián)系人

int ByNameFind(Contact* pc, char name[])//通過(guò)名字查找聯(lián)系人
{
	for (int i = 0; i < pc->sz; i++)
	{
		if (strcmp(pc->data[i].name, name) == 0)
		{
			return i;
		}
	}
	return -1;
}
void SearchContact(Contact* pc)//查找聯(lián)系人
{
	assert(pc);
	char name[NAME_MAX];
	printf("請(qǐng)輸入要查找的聯(lián)系人\n");
	scanf("%s", name);
	int ret = ByNameFind(pc, name);
	if (ret == -1)
	{
		printf("查無(wú)此人\n");
		return;
	}
	printf("%-20s\t%-4s\t%-4s\t%-12s\t%-30s\n", "姓名", "年齡", "性別", "電話號(hào)碼", "地址");
	printf("%-20s\t%-4d\t%-4s\t%-12s\t%-30s\n", pc->data[ret].name,
		pc->data[ret].age,
		pc->data[ret].sex,
		pc->data[ret].tele,
		pc->data[ret].addr);
}

注意:名字屬于字符串,名字的比較需要用strcmp來(lái)比較,如果返回-1,則是沒(méi)有找到聯(lián)系人,如果找到了,則就打印這個(gè)聯(lián)系人的信息出來(lái)

6.修改聯(lián)系人

void ModifyContact(Contact* pc)//修改聯(lián)系人
{
	assert(pc);
	char name[NAME_MAX];
	printf("請(qǐng)輸入要修改的聯(lián)系人姓名\n");
	scanf("%s", name);
	int pos = ByNameFind(pc, name);
	if (pos == -1)
	{
		printf("找不到該聯(lián)系人\n");
		return;
	}
	printf("請(qǐng)輸入姓名:\n");
	scanf("%s", pc->data[pos].name);
	printf("請(qǐng)輸入年齡:\n");
	scanf("%d", &(pc->data[pos].age));
	printf("請(qǐng)輸入性別:\n");
	scanf("%s", pc->data[pos].sex);
	printf("請(qǐng)輸入號(hào)碼:\n");
	scanf("%s", pc->data[pos].tele);
	printf("請(qǐng)輸入地址:\n");
	scanf("%s", pc->data[pos].addr);
	printf("修改聯(lián)系人成功\n");
}

注意:想要修改這個(gè)聯(lián)系人,也需要通訊錄中有這個(gè)聯(lián)系人,所以要先查找到這個(gè)聯(lián)系人,所以調(diào)用封裝好的通過(guò)名字查找聯(lián)系人這個(gè)函數(shù)就可以了,如果返回-1,則就是沒(méi)有該聯(lián)系人,無(wú)法修改,如果找到了,則才能夠修改此聯(lián)系人的信息。

7.通過(guò)名字來(lái)排序聯(lián)系人

void ByNameSortContact(Contact* pc)//通過(guò)名字來(lái)排序
{
	assert(pc);
	if (pc->sz == 0)
	{
		printf("無(wú)聯(lián)系人,無(wú)法排序\n");
		return;
	}
	PeoInfo temp;
	for (int i = 0; i < pc->sz - 1; i++)
	{
		for(int j = 0 ;j<pc->sz-1-i;j++)
		{
			if (strcmp(pc->data[j].name, pc->data[j + 1].name) > 0)
			{
				temp = pc->data[j];
				pc->data[j] = pc->data[j + 1];
				pc->data[j + 1] = temp;
			}
		}
	}
	printf("排序成功\n");
}

注意:這里通過(guò)名字來(lái)排序聯(lián)系人,也是需要用到strcmp這個(gè)庫(kù)函數(shù)的,strcmp是一個(gè)字符來(lái)比較的,如果有一個(gè)字符大的話就要進(jìn)行交換,利用的是冒泡排序思想來(lái)排序聯(lián)系人的

8.保存聯(lián)系人到文本文件中

void SaveContact(Contact* pc)
{
	assert(pc);
	
	FILE* pf = fopen("Contact.txt", "wb");
	if (pf == NULL)
	{
		perror("fopen");
	}
	else
	{
		for (int i = 0; i < pc->sz; i++)
		{
			fwrite(pc->data + i, sizeof(PeoInfo), 1, pf);
		}
		fclose(pf);
		pf = NULL;
		printf("保存數(shù)據(jù)成功\n");
	}
}

?

注意:FILE是C語(yǔ)言標(biāo)準(zhǔn)的指針,wb是用二進(jìn)制的方式寫(xiě)入文本文件中,而fwrite的用法我們可以利用cplusplus來(lái)查找它的用法,里面介紹了它的每個(gè)參數(shù)的用法,第一個(gè)參數(shù)ptr其實(shí)就是傳我們的data的指針進(jìn)去,第二個(gè)參數(shù)本質(zhì)就是求大小的,求得是PeoInfo得大小,第三個(gè)參數(shù)就是每次添加幾個(gè)聯(lián)系人,每次添加1個(gè)。第四個(gè)參數(shù)是把文件流放入

9.從文件中讀取聯(lián)系人的信息

//從文件中初始化聯(lián)系人
void GetContact(Contact* pc)
{
	assert(pc);
 
	FILE* pf = fopen("Contact.txt", "rb");
	if (pf == NULL)
	{
		perror("GetContact::fopen");
	}
	else
	{
		PeoInfo ptr = { 0 };
		int i = 0;
		while (fread(&ptr, sizeof(PeoInfo), 1, pf))
		{
			check_capacity(pc);
			pc->data[i] = ptr;
			i++;
			pc->sz++;
		}
		fclose(pf);
		pf = NULL;
	}
}

?

注意:rb是利用二進(jìn)制來(lái)讀取聯(lián)系人的,fread的用法如上圖所示。

10.銷(xiāo)毀聯(lián)系人

//銷(xiāo)毀聯(lián)系人
void DestroyContact(Contact* pc)
{
	free(pc->data);
	pc->data = NULL;
	pc->capacity = 0;
	pc->sz = 0;
}

注意:在我們退出通訊錄時(shí),要將它進(jìn)行銷(xiāo)毀

三、text.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");
}
enum Option
{
	EXIT,
	ADD,
	DEL,
	SEARCH,
	MODIFY,
	SHOW,
	SORT
};
int main()
{
	Contact con;
	InitContact(&con);
	int input = 0;
	do
	{
		menu();
		printf("請(qǐng)輸入數(shù)字:\n");
		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 SHOW:
			ShowContact(&con);
			break;
		case SORT:
			ByNameSortContact(&con);
			break;
		case EXIT:
			SaveContact(&con);
			DestroyContact(&con);
			printf("退出程序\n");
			break;
		default:
			printf("輸入錯(cuò)誤,請(qǐng)重新輸入\n");
			break;
		}
	} while (input);
	return 0;

注意:首先要建立菜單,然后用枚舉來(lái)定義case后面,這樣為了可以讓我們看代碼更清晰,在運(yùn)行程序時(shí)要將聯(lián)系人從文件中讀取出來(lái),在退出文件時(shí),要把聯(lián)系人保存到文本文件中去,在進(jìn)行銷(xiāo)毀。

好了,小編的分享到這里就結(jié)束了,如果有什么不足的地方請(qǐng)大佬多多指教?。。?/p>

到此這篇關(guān)于C語(yǔ)言實(shí)現(xiàn)一個(gè)文件版動(dòng)態(tài)通訊錄流程詳解的文章就介紹到這了,更多相關(guān)C語(yǔ)言動(dòng)態(tài)通訊錄內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論