真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

C語言----通訊錄系統(tǒng)的實現(xiàn)-文件版本-創(chuàng)新互聯(lián)

通訊錄的最新版本來啦,請注意查收~~~

創(chuàng)新互聯(lián)服務(wù)項目包括樊城網(wǎng)站建設(shè)、樊城網(wǎng)站制作、樊城網(wǎng)頁制作以及樊城網(wǎng)絡(luò)營銷策劃等。多年來,我們專注于互聯(lián)網(wǎng)行業(yè),利用自身積累的技術(shù)優(yōu)勢、行業(yè)經(jīng)驗、深度合作伙伴關(guān)系等,向廣大中小型企業(yè)、政府機構(gòu)等提供互聯(lián)網(wǎng)行業(yè)的解決方案,樊城網(wǎng)站推廣取得了明顯的社會效益與經(jīng)濟效益。目前,我們服務(wù)的客戶以成都為中心已經(jīng)輻射到樊城省份的部分城市,未來相信會繼續(xù)擴大服務(wù)區(qū)域并繼續(xù)獲得客戶的支持與信任!

在手機中的通訊錄,與我們之前的兩個通訊錄版本相比,大的區(qū)別是每次關(guān)掉程序或者關(guān)機重啟,聯(lián)系人的信息不會像在內(nèi)存中的程序一樣丟失,而是保存在了本地的硬盤里,這一次,我們就使用C語言中的文件功能對通訊錄進(jìn)行改進(jìn)。

總結(jié)一下,需要完成的功能為:在退出時保存信息到文件;打開時加載文件中的信息到程序。

目錄

一、代碼優(yōu)化

1.退出時保存信息

(1)創(chuàng)建函數(shù)

(2)保存信息

(3)關(guān)閉文件

2.打開程序時加載文件中的信息

(1)創(chuàng)建讀取函數(shù)

(2)讀取信息

(3)關(guān)閉文件

三、文件代碼?

1.contact.h

2.contact.c

3.test.c

四、注意事項


一、代碼優(yōu)化 ??????? 1.退出時保存信息

?????我們創(chuàng)建SaveContact函數(shù)用來將信息保存至文件中,將這個函數(shù)放在switch語句中的case選項下,先存放到文件中,再銷毀程序中的通訊錄。

// test.c
...
case EXIT:
    SaveContact(&contact);
    DestoryContact(&contact);
    break;
...
(1)創(chuàng)建函數(shù)

???? 首先需要先打開文件,采用寫入的方式,我們定義FILE類型指針,指向使用fopen打開的文件,并判斷文件指針是否為空,即是否打開文件失敗,失敗就提示錯誤信息并退出函數(shù)。

(2)保存信息

????? 當(dāng)打開文件成功后,就可以進(jìn)行寫入了,我們使用for循環(huán)進(jìn)行逐個寫入,使用fwrite寫入文件,信息源為聯(lián)系人列表,每次寫入一個聯(lián)系人信息所占的字節(jié)數(shù),每次寫入一個聯(lián)系人信息,寫入文件指針類型所指向的文件中。

(3)關(guān)閉文件

???? 最后就是關(guān)閉文件了,使用fclose關(guān)閉文件,并將指針置空。

???? 每次使用文件指針后切記要關(guān)閉文件,并將指針置空,防止內(nèi)存訪問異常!

???? 函數(shù)代碼如下:

// contact.c
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++)
	{
		// 要寫入的信息來源為聯(lián)系人列表;每次寫入一個聯(lián)系人的信息大??;
		// 每次寫入一個聯(lián)系人信息;寫入pf所指向的文件中
		fwrite(pc->data+i, sizeof(PeoInfo), 1,pf);
	}

	// 關(guān)閉文件
	fclose(pf);
	pf = NULL;
}
2.打開程序時加載文件中的信息

加載文件就是指讀取文件中的內(nèi)容到程序中,我們創(chuàng)建LoadContact函數(shù)用來讀取文件中的信息。

需要注意的是,我們應(yīng)該在程序初始化時讀取文件的內(nèi)容,而不是到用戶選擇功能時再進(jìn)行讀取。將讀取文件的函數(shù)放在初始化函數(shù)中。

// contact.c
void InitContact(Contact* pc)
{
    ...
    LoadContact(pc);
}
(1)創(chuàng)建讀取函數(shù)

???? a.讀取文件

???????????? 使用FILE類型指針指向使用fopen打開存放信息的文件"contact.dat",需要注意的是,這里應(yīng)當(dāng)使用"r"對文件進(jìn)行讀取。要記得進(jìn)行判斷是否打開成功~

(2)讀取信息

??????????? 使用fread對信息進(jìn)行讀取,創(chuàng)建一個臨時的聯(lián)系人列表temp用來存放讀取得到的信息,并對temp進(jìn)行判斷:

????? 若讀取為0表示文件中沒有信息;

?????若讀取成功就將讀取的信息存放到程序中創(chuàng)建的通訊錄中,這時候文件中的聯(lián)系人數(shù)量可能會大于我們設(shè)置的默認(rèn)數(shù)量,需要判斷是否需要對容量進(jìn)行增加,我們使用CheckCapicaty函數(shù)進(jìn)行判斷。

// contact.c
void LoadContact(Contact* pc)
{
    ...
    CheckCapacity(pc);
    ...
}

???? 具體的CheckCapacity函數(shù)在動態(tài)版本中已有寫明,可移步查看。

???? 我們將臨時列表中的信息存放到程序中的通訊錄中,使用while函數(shù)進(jìn)行判斷,當(dāng)讀取的信息不為空時,將聯(lián)系人信息逐條轉(zhuǎn)存到聯(lián)系人列表中,為空時就退出程序。

(3)關(guān)閉文件

??????? 在讀取完成后,文件中的聯(lián)系人信息已被存至程序中的通訊錄中,直到退出通訊錄時才需要再次打開文件進(jìn)行寫入,故在完成讀取后需要關(guān)閉文件。

???? 函數(shù)代碼如下:

// contact.c
void LoadContact(Contact* pc)
{
	FILE* pf = fopen("contact.dat", "r");
	if (pf == NULL)
	{
		perror("LoadContact");
		return;
	}
	// 讀文件
	PeoInfo temp = { 0 };
	while (fread(&temp, sizeof(PeoInfo), 1, pf))
	{
		// 是否需要增容
		CheckCapacity(pc);
		pc->data[pc->sz] = temp;
		pc->sz++;
	}

	// 關(guān)閉文件
	fclose(pf);
	pf = NULL;
}
三、文件代碼? ??????? 1.contact.h
#define _CRT_SECURE_NO_WARNINGS 1

#pragma warning(disable:6031)

// 相關(guān)函數(shù)的聲明
// 一些類型的定義

#include#include#include#define MAX_NAME 20
#define MAX_SEX 10
#define MAX_TEL 15
#define MAX_ADDR 30
#define MAX 1000
#define DEFAULT_SZ 3
#define INC_SZ 2


// 聯(lián)系人的存放
// 使用typedef 定義結(jié)構(gòu)體類型,方便調(diào)用
typedef struct PeoInfo
{
	char name[MAX_NAME];		// 姓名
	char sex[MAX_SEX];			// 性別
	int age;					// 年齡
	char tel[MAX_TEL];			// 電話
	char addr[MAX_ADDR];		// 地址
}PeoInfo;

// 通訊錄
typedef struct Contact
{
	PeoInfo* data;	// 指向動態(tài)申請的空間,用來存放聯(lián)系人的信息
	int sz;			// 通訊錄中具體的聯(lián)系人數(shù)量
	int capacity;	// 記錄當(dāng)前通訊錄的大容量
}Contact;


// 初始化通訊錄
void InitContact(Contact* pc);

// 增加聯(lián)系人
void AddContact(Contact* pc);

// 打印聯(lián)系人
void PrintContact(const Contact* pc);

// 刪除聯(lián)系人
void DelContact(Contact* pc);

// 查找聯(lián)系人
void SearchContact(Contact* pc);

// 修改聯(lián)系人
void ModifyContact(Contact* pc);

// 排序聯(lián)系人
void SortContact(Contact* pc);

// 銷毀通訊錄
void DestorContact(Contact* pc);

// 保存通訊錄信息
void SaveContact(Contact* pc);
2.contact.c
#define _CRT_SECURE_NO_WARNINGS 1

#pragma warning(disable:6031)


// 具體的功能函數(shù)的實現(xiàn)


#include"contact.h"

// 保存信息到文件中 
void SaveContact(Contact* pc)
{
	// 打開文件
	FILE* pf = fopen("contact.dat", "w");
	if (pf == NULL)
	{
		perror("SaveContact");
		return;
	}
	// 寫文件
	int i = 0;
	for (i = 0; i< pc->sz; i++)
	{
		// 要寫入的信息來源為聯(lián)系人列表;每次寫入一個聯(lián)系人的信息大??;
		// 每次寫入一個聯(lián)系人信息;寫入pf所指向的文件中
		fwrite(pc->data + i, sizeof(PeoInfo), 1, pf);
	}

	// 關(guān)閉文件
	fclose(pf);
	pf = NULL;
}


// 判斷是否需要增容
void CheckCapacity(Contact* pc)
{
	if (pc->sz == pc->capacity)
	{
		PeoInfo* ptr = (PeoInfo*)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("增加聯(lián)系人失敗\n");
			return;
		}
	}
}

void LoadContact(Contact* pc)
{
	FILE* pf = fopen("contact.dat", "r");
	if (pf == NULL)
	{
		// 提示錯誤并返回
		perror("LoadContact");
		return;
	}
	// 讀取文件
	PeoInfo temp = { 0 };
	while (fread(&temp, sizeof(PeoInfo), 1, pf))
	{
		// 是否需要增容
		CheckCapacity(pc);
		pc->data[pc->sz] = temp;
		pc->sz++;
	}

	// 關(guān)閉文件
	fclose(pf);
	pf = NULL;
}


// 文件版本-初始化通訊錄
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);
}





// 動態(tài)版本——增加聯(lián)系人
void AddContact(Contact* pc)
{
	// 判斷空間是否足夠
	CheckCapacity(pc);
	// 增加聯(lián)系人信息
	printf("請輸入姓名:>");
	scanf("%s", pc->data[pc->sz].name);
	printf("請輸入性別:>");
	scanf("%s", pc->data[pc->sz].sex);
	printf("請輸入年齡:>");
	// 變量需要使用&
	scanf("%d", &pc->data[pc->sz].age);
	printf("請輸入電話:>");
	scanf("%s", pc->data[pc->sz].tel);
	printf("請輸入地址:>");
	scanf("%s", pc->data[pc->sz].addr);

	// 使聯(lián)系人數(shù)量+1
	pc->sz++;
	printf("增加成功\n");
}

// 動態(tài)版本——銷毀通訊錄
void DestorContact(Contact* pc)
{
	free(pc->data);
	pc->data = NULL;
	pc->sz = 0;
	pc->capacity = 0;
}

// 打印聯(lián)系人——加上const確保在函數(shù)內(nèi)部聯(lián)系人信息不會被改變
void PrintContact(const Contact* pc)
{
	if (pc->sz == 0)
	{
		printf("通訊錄中無聯(lián)系人信息,無需打印\n");
		return;
	}
	// 打印表頭
	printf("%-10s\t%-10s\t%-10s\t%-10s\t%-10s\n", "姓名", "性別", "年齡", "電話", "地址");

	// 打印聯(lián)系人信息
	int i = 0;
	for (i = 0; i< pc->sz; i++)
	{
		printf("%-10s\t%-10s\t%-10d\t%-10s\t%-10s\n",
			pc->data[i].name,
			pc->data[i].sex,
			pc->data[i].age,
			pc->data[i].tel,
			pc->data[i].addr
		);
	}
	printf("打印完成\n");
}

// 通過姓名查找聯(lián)系人
// 創(chuàng)建查找函數(shù),方便被刪除修改和查找時調(diào)用
// 使用static 使得此函數(shù)只能在本函數(shù)內(nèi)部被調(diào)用和查看
static int FindName(const Contact* pc, const char input_name[])
{
	int i = 0;
	for (i = 0; i< pc->sz; i++)
	{
		// strcmp的結(jié)果為0時是找到了對應(yīng)的姓名
		if (strcmp(pc->data[i].name, input_name) == 0)
		{
			// 則返回對應(yīng)的聯(lián)系人信息下標(biāo)
			return i;
		}
	}
	// 找不到
	return -1;
}



// 刪除聯(lián)系人
void DelContact(Contact* pc)
{
	// 判斷通訊錄是否為空
	if (pc->sz == 0)
	{
		printf("通訊錄為空,無需刪除\n");
		return;
	}
	// 查找要刪除的人
	char input_name[MAX_NAME];
	printf("請輸入要刪除人的姓名:>");
	scanf("%s", input_name);
	// 設(shè)定ret判斷返回結(jié)果
	int ret = FindName(pc, input_name);
	// 當(dāng)查找失敗時
	if (ret == -1)
	{
		printf("要刪除的人不存在\n");
		return;
	}
	// 刪除后,將刪除聯(lián)系人之后的聯(lián)系人信息的下標(biāo)-1
	int i = 0;
	for (i = ret; i< pc->sz; i++)
	{
		pc->data[i] = pc->data[i + 1];
	}
	// 刪除成功后使聯(lián)系人數(shù)量減1
	pc->sz--;
	printf("刪除成功\n");
}

// 查找聯(lián)系人
void SearchContact(Contact* pc)
{
	char find_name[MAX_NAME] = { 0 };
	printf("請輸入查找的聯(lián)系人姓名:>");
	scanf("%s", find_name);
	int ret = FindName(pc, find_name);
	if (ret == -1)
	{
		printf("查無此人\n");
		return;
	}
	else
	{
		printf("%-10s\t%-10s\t%-10s\t%-10s\t%-10s\n", "姓名", "性別", "年齡", "電話", "地址");
		printf("%-10s\t%-10s\t%-10d\t%-10s\t%-10s\n",
			pc->data[ret].name,
			pc->data[ret].sex,
			pc->data[ret].age,
			pc->data[ret].tel,
			pc->data[ret].addr
		);
		printf("查找完畢\n");
	}
}

// 修改聯(lián)系人
void ModifyContact(Contact* pc)
{
	char input_name[MAX_NAME] = { 0 };
	printf("請輸入要修改的聯(lián)系人的姓名:>");
	scanf("%s", input_name);
	int ret = FindName(pc, input_name);
	if (ret == -1)
	{
		printf("查無此人,無法修改\n");
		return;
	}
	printf("請輸入姓名:>");
	scanf("%s", pc->data[ret].name);
	printf("請輸入性別:>");
	scanf("%s", pc->data[ret].sex);
	printf("請輸入年齡:>");
	// 變量需要使用&
	scanf("%d", &pc->data[ret].age);
	printf("請輸入電話:>");
	scanf("%s", pc->data[ret].tel);
	printf("請輸入地址:>");
	scanf("%s", pc->data[ret].addr);
	printf("修改完畢\n");
}

// 創(chuàng)建比較函數(shù)
int cmp_name(const void* p1, const void* p2)
{
	return strcmp(((PeoInfo*)p1)->name, ((PeoInfo*)p2)->name);
}

// 排序聯(lián)系人
void SortContact(Contact* pc)
{
	// 判斷通訊錄是否為空
	if (pc->sz == 0)
	{
		printf("通訊錄為空,無需排序\n");
		return;
	}
	// 以姓名為排序依據(jù)進(jìn)行排序

	// 使用qsort函數(shù)進(jìn)行排序——調(diào)用了創(chuàng)建的cmp_name()
	// 待排序列地址、待排關(guān)鍵字個數(shù)、關(guān)鍵字大小、比較函數(shù)地址
	qsort(pc->data, pc->sz, sizeof(PeoInfo), cmp_name);

	printf("排序成功\n");

}
3.test.c
#define _CRT_SECURE_NO_WARNINGS 1

#pragma warning(disable:6031)

// 測試文件

// 文件版本
// 當(dāng)退出通訊錄時,將聯(lián)系人信息保存到文件中
// 當(dāng)打開通訊錄時,加載文件中的聯(lián)系人信息到程序中
// 

#include"contact.h"


void menu()
{
	printf("*******************\n");
	printf("****  1.add    ****\n");		// 增加聯(lián)系人信息
	printf("****  2.del    ****\n");		// 刪除聯(lián)系人信息
	printf("****  3.serach ****\n");		// 查找聯(lián)系人信息
	printf("****  4.modify ****\n");		// 修改聯(lián)系人信息
	printf("****  5.sort   ****\n");		// 排序聯(lián)系人信息
	printf("****  6.print  ****\n");		// 打印聯(lián)系人信息
	printf("****  0.exit   ****\n");		// 退出通訊錄
	printf("*******************\n");
}

// 使用枚舉,使得switch選擇時,更加明了
enum Menu
{
	EXIT,		// 默認(rèn)為 0 
	ADD,		// 1
	DEL,
	SEARCH,
	MODIFY,
	SORT,
	PRINT
};

int main()		// 在靜態(tài)模式下會因為數(shù)據(jù)過多報警告
{
	int input = 0;

	// 創(chuàng)建通訊錄
	Contact contact;

	// 初始化通訊錄
	InitContact(&contact);

	do
	{
		menu();
		printf("請選擇:>");
		scanf("%d", &input);
		switch (input)
		{
		case ADD:
			AddContact(&contact);
			break;
		case DEL:
			DelContact(&contact);
			break;
		case SEARCH:
			SearchContact(&contact);
			break;
		case MODIFY:
			ModifyContact(&contact);
			break;
		case SORT:
			SortContact(&contact);
			break;
		case PRINT:
			PrintContact(&contact);
			break;
		case EXIT:
			// 保存信息到文件
			SaveContact(&contact);
			DestorContact(&contact);
			printf("程序結(jié)束\n");
			break;
		default:
			printf("選擇錯誤,請重新選擇:\n");
		}
	} while (input);
	return 0;
}
四、注意事項

1.在之前兩個版本中,有少許代碼無用,不影響功能的執(zhí)行,在當(dāng)前版本進(jìn)行了適當(dāng)優(yōu)化。

2.目前為止的三個版本分別對應(yīng)不同的C語言內(nèi)容,可根據(jù)自身學(xué)習(xí)進(jìn)度進(jìn)行實現(xiàn),做到先理解,再獨立完成。不要沒有學(xué)習(xí)對應(yīng)的內(nèi)容就進(jìn)行編寫,一口吃不成胖子,學(xué)習(xí)急不得。

3.通訊錄的編寫告一段落,日后若有新的想法或者更新,將會編寫相關(guān)的文章用來講述。

4.gitee鏈接

shiwuqing-Contact-3

?????

你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機房具備T級流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級服務(wù)器適合批量采購,新人活動首月15元起,快前往官網(wǎng)查看詳情吧


文章標(biāo)題:C語言----通訊錄系統(tǒng)的實現(xiàn)-文件版本-創(chuàng)新互聯(lián)
當(dāng)前URL:http://weahome.cn/article/dcecdd.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部