国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

動(dòng)態(tài)通訊錄實(shí)現(xiàn)(C語(yǔ)言)

這篇具有很好參考價(jià)值的文章主要介紹了動(dòng)態(tài)通訊錄實(shí)現(xiàn)(C語(yǔ)言)。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

目錄

前言:

一:?jiǎn)蝹€(gè)節(jié)點(diǎn)的設(shè)計(jì)和主邏輯?

結(jié)點(diǎn)設(shè)計(jì)

主邏輯

二:接口實(shí)現(xiàn)

(1)生成一個(gè)新的結(jié)點(diǎn)

(2)增加信息

(3)打印信息

(4)查找?

(5)刪除信息

(6)修改信息

(7)排序

?插入排序

快速排序

(8)已有數(shù)據(jù)讀取

(9)更新數(shù)據(jù)錄入

三:全部代碼

contact.h(聲明)

contact.c(接口)

test.c(主邏輯)


前言:

本文使用的存儲(chǔ)結(jié)構(gòu)是不帶哨兵位鏈表,還包含了文件操作(讀取和錄入),有類似課程設(shè)計(jì)的同學(xué)可能需要(完整代碼在最后)。

鏈表(知道基礎(chǔ)概念,清楚形參實(shí)參關(guān)系的可以不看):

https://blog.csdn.net/2301_76269963/article/details/129586021?spm=1001.2014.3001.5502


一:?jiǎn)蝹€(gè)節(jié)點(diǎn)的設(shè)計(jì)和主邏輯?

結(jié)點(diǎn)設(shè)計(jì)

需求:一個(gè)人要包含姓名、年齡、性別、電話號(hào)碼、地址這些信息,把這些信息封裝成一個(gè)結(jié)構(gòu)體。

動(dòng)態(tài)通訊錄實(shí)現(xiàn)(C語(yǔ)言)


要讓每個(gè)人的數(shù)據(jù)鏈接成一個(gè)整體,節(jié)點(diǎn)除了個(gè)人信息之外還要保存下個(gè)結(jié)點(diǎn)的地址。

動(dòng)態(tài)通訊錄實(shí)現(xiàn)(C語(yǔ)言)


主邏輯

(1)每次開(kāi)始都從文件中讀取數(shù)據(jù)

(2)通訊錄的功能包括:①增加數(shù)據(jù)

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?②依據(jù)名字刪除數(shù)據(jù)

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?③依據(jù)名字查找數(shù)據(jù)

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?④依據(jù)名字修改數(shù)據(jù)

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?⑤依據(jù)年齡排序數(shù)據(jù)

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?⑥打印數(shù)據(jù)

(3)退出后重新錄入數(shù)據(jù)


二:接口實(shí)現(xiàn)

(1)生成一個(gè)新的結(jié)點(diǎn)

//生成一個(gè)新節(jié)點(diǎn)
Node* BuyNewNode()
{
	Node* NewNode = (Node*)malloc(sizeof(Node));
	if (NewNode == NULL)
	{
		printf("malloc error\n");
		exit(-1);
	}
	NewNode->next = NULL;

	printf("請(qǐng)輸入名字:");
	scanf("%s", NewNode->data.name);
	printf("請(qǐng)輸入年齡:");
	scanf("%d", &NewNode->data.age);
	printf("請(qǐng)輸入性別:");
	scanf("%s", NewNode->data.sex);
	printf("請(qǐng)輸入電話:");
	scanf("%s", NewNode->data.tele);
	printf("請(qǐng)輸入地址:");
	scanf("%s", NewNode->data.addr);

	return NewNode;
}

(2)增加信息

//增加信息,可能要更改頭指針,傳二級(jí)指針修改一級(jí)指針
void AddContact(Node** pphead)
{
	//生成新節(jié)點(diǎn)
	Node* NewNode = BuyNewNode();
	//單獨(dú)處理空的情況
	if (*pphead == NULL)
	{
		*pphead = NewNode;
		return;
	}
	else
	{
		NewNode->next = *pphead;
		*pphead = NewNode;
	}
}

圖解:

動(dòng)態(tài)通訊錄實(shí)現(xiàn)(C語(yǔ)言)

(3)打印信息

//打印信息
void PrintContact(Node* phead)
{
	//注意打印格式,加-表示字符左對(duì)齊,數(shù)字表示最小字符數(shù)(不足補(bǔ)空格)
	printf("%-20s\t%-5s\t%-5s\t%-20s\t%-20s\n", "名字", "年齡", "性別", "電話", "地址");
	while (phead != NULL)
	{
		printf("%-20s\t%-5d\t%-5s\t%-20s\t%-20s\n", 
			   phead->data.name,phead->data.age,
			   phead->data.sex,phead->data.tele,phead->data.addr);
		//迭代
		phead = phead->next;
	}
}

(4)查找?

注意:后續(xù)的刪除和修改都需要用到查找,為增強(qiáng)代碼復(fù)用性,查找函數(shù)返回結(jié)點(diǎn)的地址,如果未查找到就返回空。

//查找,第二個(gè)參數(shù)為名字字符串首地址
Node* FindContact(Node* phead,char* name)
{
	//遍歷鏈表
	while (phead)
	{
		//strcmp()函數(shù)用于字符串比較,相同返回0,否則返回非0值
		if (strcmp(phead->data.name, name) == 0)
		{
			return phead;
		}
		phead = phead->next;
	}
	//沒(méi)找到返回空
	return NULL;
}

(5)刪除信息

先查找,找到待刪除結(jié)點(diǎn)地址,如果待刪除結(jié)點(diǎn)為頭節(jié)點(diǎn),需要更新頭指針;

否則就需要找到待刪除結(jié)點(diǎn)的前一個(gè)結(jié)點(diǎn),前一個(gè)結(jié)點(diǎn)指針域指向待刪除結(jié)點(diǎn)的下一個(gè)結(jié)點(diǎn),然后釋放待刪除結(jié)點(diǎn)。

//刪除信息,可能要更改頭指針,傳二級(jí)指針修改一級(jí)指針
void DelContact(Node** pphead)
{
	//信息為空不能刪除
	assert(*pphead != NULL);
	
	//查找
	char name[max_name];
	printf("請(qǐng)輸入要?jiǎng)h除聯(lián)系人的名字:");
	scanf("%s", name);
	Node* pos = FindContact(*pphead,name);
	if (pos == NULL)
	{
		printf("查找失敗\n");
		return;
	}

	//如果pos是第一個(gè)節(jié)點(diǎn)
	if (pos == *pphead)
	{
		//找到下一個(gè)
		Node* NEXT = pos->next;
		free(pos);
		*pphead = NEXT;
	}
	else
	{
		//找到前一個(gè)
		Node* prev = *pphead;
		while (prev->next != pos)
		{
			prev = prev->next;
		}
		prev->next = pos->next;
		free(pos);
	}
	printf("刪除成功\n");
}

圖解:

動(dòng)態(tài)通訊錄實(shí)現(xiàn)(C語(yǔ)言)

(6)修改信息

先查找到目標(biāo)結(jié)點(diǎn),然后進(jìn)行修改。

//修改信息
void ModifyContact(Node* phead)
{
	//查找
	char name[max_name];
	printf("請(qǐng)輸入要修改聯(lián)系人的名字:");
	scanf("%s", name);
	Node* pos = FindContact(phead, name);
	if (pos == NULL)
	{
		printf("查找失敗\n");
		return;
	}
	else
	{
		printf("找到了,進(jìn)行修改\n");
		printf("請(qǐng)輸入名字:");
		scanf("%s", pos->data.name);
		printf("請(qǐng)輸入年齡:");
		scanf("%d", &pos->data.age);
		printf("請(qǐng)輸入性別:");
		scanf("%s", pos->data.sex);
		printf("請(qǐng)輸入電話:");
		scanf("%s", pos->data.tele);
		printf("請(qǐng)輸入地址:");
		scanf("%s", pos->data.addr);
	}
}

(7)排序

這里給兩種實(shí)現(xiàn)方式,第一種使用插入排序(方便理解)第二種使用快速排序(效率更快,有空間消耗,代碼量更多)


?插入排序

插入排序的核心思想是:將一個(gè)未排序的元素插入到已排序的子序列中,使得插入后依然保持有序。具體實(shí)現(xiàn)時(shí),我們可以從第二個(gè)元素開(kāi)始,將其與前面已排序序列的元素比較,找到其正確的插入位置,然后插入即可。在插入過(guò)程中,需要將已排序序列中比該元素大的元素后移,為該元素騰出插入位置(看一遍就可以看代碼和圖解)。

//交換數(shù)據(jù)
void swap(Node* p1, Node* p2)
{
	struct PepInfo tmp = p1->data;
	p1->data = p2->data;
	p2->data = tmp;
}

//進(jìn)行排序
void sort(Node* phead)
{
	//空不排序
	assert(phead != NULL);

	Node* begin = phead;
	Node* end = phead->next;
	while (end)
	{
		while (begin != end)
		{
			if (begin->data.age > end->data.age)
			{
				swap(begin,end);
			}
			begin = begin->next;
		}
        //更新
		end = end->next;
		begin = phead;
	}
}

圖解:

動(dòng)態(tài)通訊錄實(shí)現(xiàn)(C語(yǔ)言)


快速排序

這里就不展開(kāi)講快速排序的思想了,也不建議用快速排序,一般通訊錄這樣的數(shù)據(jù)量用插入排序就足夠了,感興趣的同學(xué)可以看鏈接。

快速排序鏈接:https://blog.csdn.net/2301_76269963/article/details/130473353?spm=1001.2014.3001.5502

先將鏈表中的數(shù)據(jù)拷貝到數(shù)組中,對(duì)數(shù)組進(jìn)行排序,再把數(shù)組數(shù)據(jù)拷貝回鏈表。

//交換數(shù)據(jù)
void swap(PepInfo* p1, PepInfo* p2)
{
	PepInfo tmp = *p1;
	*p1 = *p2;
	*p2 = tmp;
}

// 三數(shù)取中
int GetMidIndex(PepInfo* a, int left, int right)
{
	int midi = left + (right - left) / 2;

	if (a[midi].age > a[right].age)
	{
		if (a[midi].age < a[left].age)
			return midi;
		else if (a[right].age > a[left].age)
			return right;
		else
			return left;
	}
	else    //a[right] > a[mid]
	{
		if (a[midi].age > a[left].age)
			return midi;
		else if (a[left].age < a[right].age)
			return left;
		else
			return right;
	}
}

//前后指針?lè)?int partion3(PepInfo* a, int left, int right)
{
	int midi = GetMidIndex(a, left, right);
	swap(&a[midi], &a[left]);

	int keyi = left;
	int prev = left;
	int cur = left + 1;
	while (cur <= right)
	{
		//++prev和cur相等,無(wú)效交換,不換
		if (a[cur].age < a[keyi].age && ++prev != cur)
		{
			swap(&a[prev], &a[cur]);
		}
		cur++;
	}
	swap(&a[keyi], &a[prev]);
	return prev;
}

//快速排序
void QuickSort(PepInfo* a, int left, int right)
{
	//如果left>right,區(qū)間不存在
	//left==right,只有一個(gè)元素,可以看成是有序的
	if (left >= right)
	{
		return;
	}
	else
	{
		//單次排序
		int keyi = partion3(a, left, right);
		//分成左右區(qū)間,排序左右區(qū)間
		QuickSort(a, left, keyi - 1);
		QuickSort(a, keyi + 1, right);
	}
}

// 鏈表快速排序函數(shù)
void sortList(Node* phead) 
{
	// 處理空或單節(jié)點(diǎn)鏈表的情況
	if (!phead || !phead->next)
	{
		return;
	}

	//求鏈表長(zhǎng)度
	int len = 0;
	Node* cur = phead;
	while (cur) 
	{
		len++;
		cur = cur->next;
	}

	// 將鏈表轉(zhuǎn)換為數(shù)組
	PepInfo* arr = malloc(len * sizeof(PepInfo));
	if (arr == NULL)
	{
		printf("malloc error\n");
		exit(-1);
	}
	cur = phead;
	for (int i = 0; i < len; i++) 
	{
		arr[i] = cur->data;
		cur = cur->next;
	}

	// 快速排序
	QuickSort(arr, 0, len - 1);

	// 將數(shù)組轉(zhuǎn)換為鏈表
	cur = phead;
	for (int i = 0; i < len; i++) 
	{
		cur->data = arr[i];
		cur = cur->next;
	}

	free(arr);
}

(8)已有數(shù)據(jù)讀取

①生成一個(gè)新結(jié)點(diǎn),將讀取的數(shù)據(jù)存入新結(jié)點(diǎn)中。

②第一次讀取時(shí)鏈表為空,修改頭指針。

③后面的新結(jié)點(diǎn)鏈接到鏈表的尾部。

(注意:讀模式打開(kāi)文件需要文件夾中有這個(gè)文件,第一次需要手動(dòng)創(chuàng)建一個(gè)data.txt文件)

//已有數(shù)據(jù)讀取,可能要更改頭指針,傳二級(jí)指針修改一級(jí)指針
void StartFileEntry(Node** pphead)
{
	FILE* pf = fopen("data.txt", "rb");
	if (pf == NULL)
	{
		printf("打開(kāi)文件失敗\n");
		exit(-1);
	}

	//保存讀取到的數(shù)據(jù)
	PepInfo* tmp = (PepInfo*)malloc(sizeof(PepInfo));
	if (tmp == NULL)
	{
		printf("malloc error\n");
		exit(-1);
	}
	//先讀取一次
	fread(tmp, sizeof(PepInfo), 1, pf);
	//保存尾部節(jié)點(diǎn)地址
	Node* tail = NULL;
	
	//讀取到結(jié)尾時(shí)feof()返回0,未讀取到結(jié)尾返回非0值
	while (!feof(pf))
	{
		//生成新節(jié)點(diǎn)
		Node* NewNode = (Node*)malloc(sizeof(Node));
		if (NewNode == NULL)
		{
			printf("malloc error\n");
			exit(-1);
		}
		NewNode->data = *tmp;
		NewNode->next = NULL;
		//第一次頭為空,更新
		if (*pphead == NULL)
		{
			*pphead = NewNode;
			tail = *pphead;
		}
		//頭不為空,新節(jié)點(diǎn)鏈接到尾后面,尾指針更新
		else
		{
			tail->next = NewNode;
			tail = tail->next;
		}
		//繼續(xù)讀取
		fread(tmp, sizeof(PepInfo), 1, pf);
	}
	fclose(pf);
}

(9)更新數(shù)據(jù)錄入

鏈表為空,直接返回;否則遍歷鏈表,依次錄入數(shù)據(jù)。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-454312.html

//新數(shù)據(jù)錄入
void UpdateFileEntry(Node* phead)
{
	FILE* pf = fopen("data.txt", "wb");
	if (phead == NULL)
	{
		return;
	}
	else
	{
		while (phead)
		{
			fwrite(&(phead->data), sizeof(PepInfo), 1, pf);
			phead = phead->next;
		}
	}
	fclose(pf);
}

三:全部代碼

contact.h(聲明)

#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
//方便后面更改這些信息的最大容量
#define max_name 20
#define max_tele 20
#define max_addr 20
#define max_sex 10

//個(gè)人信息
typedef struct PepInfo
{
	char name[max_name];
	int age;
	char sex[max_sex];
	char tele[max_tele];
	char addr[max_addr];
}PepInfo;

typedef struct Node
{
	//個(gè)人信息
	struct PepInfo data;
	//指針域
	struct Node* next;
}Node;


//生成一個(gè)新節(jié)點(diǎn)
Node* BuyNewNode();

//增加信息,可能要更改頭指針,傳二級(jí)指針修改一級(jí)指針
void AddContact(Node** pphead);

//打印信息
void PrintContact(Node* phead);

//查找
Node* FindContact(Node* phead, char* name);

//刪除信息,可能要更改頭指針,傳二級(jí)指針修改一級(jí)指針
void DelContact(Node** pphead);

//修改信息
void ModifyContact(Node* phead);

//進(jìn)行排序
// 鏈表快速排序函數(shù)
void sortList(Node* phead);
//插入排序
void sort(Node* phead);

//已有數(shù)據(jù)讀取,可能要更改頭指針,傳二級(jí)指針修改一級(jí)指針
void StartFileEntry(Node** pphead);

//更新數(shù)據(jù)錄入
void UpdateFileEntry(Node* phead);

contact.c(接口)

#define _CRT_SECURE_NO_WARNINGS 1
#include "contact.h"

//生成一個(gè)新節(jié)點(diǎn)
Node* BuyNewNode()
{
	Node* NewNode = (Node*)malloc(sizeof(Node));
	if (NewNode == NULL)
	{
		printf("malloc error\n");
		exit(-1);
	}
	NewNode->next = NULL;

	printf("請(qǐng)輸入名字:");
	scanf("%s", NewNode->data.name);
	printf("請(qǐng)輸入年齡:");
	scanf("%d", &NewNode->data.age);
	printf("請(qǐng)輸入性別:");
	scanf("%s", NewNode->data.sex);
	printf("請(qǐng)輸入電話:");
	scanf("%s", NewNode->data.tele);
	printf("請(qǐng)輸入地址:");
	scanf("%s", NewNode->data.addr);

	return NewNode;
}

//增加信息,可能要更改頭指針,傳二級(jí)指針修改一級(jí)指針
void AddContact(Node** pphead)
{
	//生成新節(jié)點(diǎn)
	Node* NewNode = BuyNewNode();
	//單獨(dú)處理空的情況
	if (*pphead == NULL)
	{
		*pphead = NewNode;
		return;
	}
	else
	{
		NewNode->next = *pphead;
		*pphead = NewNode;
	}
}

//打印信息
void PrintContact(Node* phead)
{
	//注意打印格式,加-表示字符左對(duì)齊,數(shù)字表示最小字符數(shù)(不足補(bǔ)空格)
	printf("%-20s\t%-5s\t%-5s\t%-20s\t%-20s\n", "名字", "年齡", "性別", "電話", "地址");
	while (phead != NULL)
	{
		printf("%-20s\t%-5d\t%-5s\t%-20s\t%-20s\n", 
			   phead->data.name,phead->data.age,
			   phead->data.sex,phead->data.tele,phead->data.addr);
		//迭代
		phead = phead->next;
	}
}

//查找,第二個(gè)參數(shù)為名字字符串首地址
Node* FindContact(Node* phead,char* name)
{
	//遍歷鏈表
	while (phead)
	{
		//strcmp()函數(shù)用于字符串比較,相同返回0,否則返回非0值
		if (strcmp(phead->data.name, name) == 0)
		{
			return phead;
		}
		phead = phead->next;
	}
	//沒(méi)找到返回空
	return NULL;
}

//刪除信息,可能要更改頭指針,傳二級(jí)指針修改一級(jí)指針
void DelContact(Node** pphead)
{
	//斷言,信息為空不能刪除
	assert(*pphead != NULL);
	
	//查找
	char name[max_name];
	printf("請(qǐng)輸入要?jiǎng)h除聯(lián)系人的名字:");
	scanf("%s", name);
	Node* pos = FindContact(*pphead,name);
	if (pos == NULL)
	{
		printf("查找失敗\n");
		return;
	}

	//如果pos是第一個(gè)節(jié)點(diǎn)
	if (pos == *pphead)
	{
		//找到下一個(gè)
		Node* NEXT = pos->next;
		free(pos);
		*pphead = NEXT;
	}
	else
	{
		//找到前一個(gè)
		Node* prev = *pphead;
		while (prev->next != pos)
		{
			prev = prev->next;
		}
		prev->next = pos->next;
		free(pos);
	}
	printf("刪除成功\n");
}

//修改信息
void ModifyContact(Node* phead)
{
	//查找
	char name[max_name];
	printf("請(qǐng)輸入要修改聯(lián)系人的名字:");
	scanf("%s", name);
	Node* pos = FindContact(phead, name);
	if (pos == NULL)
	{
		printf("查找失敗\n");
		return;
	}
	else
	{
		printf("找到了,進(jìn)行修改\n");
		printf("請(qǐng)輸入名字:");
		scanf("%s", pos->data.name);
		printf("請(qǐng)輸入年齡:");
		scanf("%d", &pos->data.age);
		printf("請(qǐng)輸入性別:");
		scanf("%s", pos->data.sex);
		printf("請(qǐng)輸入電話:");
		scanf("%s", pos->data.tele);
		printf("請(qǐng)輸入地址:");
		scanf("%s", pos->data.addr);
	}
}

交換數(shù)據(jù)
//void swap(PepInfo* p1, PepInfo* p2)
//{
//	PepInfo tmp = *p1;
//	*p1 = *p2;
//	*p2 = tmp;
//}
//
 三數(shù)取中
//int GetMidIndex(PepInfo* a, int left, int right)
//{
//	int midi = left + (right - left) / 2;
//
//	if (a[midi].age > a[right].age)
//	{
//		if (a[midi].age < a[left].age)
//			return midi;
//		else if (a[right].age > a[left].age)
//			return right;
//		else
//			return left;
//	}
//	else // a[right] > a[mid]
//	{
//		if (a[midi].age > a[left].age)
//			return midi;
//		else if (a[left].age < a[right].age)
//			return left;
//		else
//			return right;
//	}
//}
//
前后指針?lè)?//int partion3(PepInfo* a, int left, int right)
//{
//	int midi = GetMidIndex(a, left, right);
//	swap(&a[midi], &a[left]);
//
//	int keyi = left;
//	int prev = left;
//	int cur = left + 1;
//	while (cur <= right)
//	{
//		//++prev和cur相等,無(wú)效交換,不換
//		if (a[cur].age < a[keyi].age && ++prev != cur)
//		{
//			swap(&a[prev], &a[cur]);
//		}
//		cur++;
//	}
//	swap(&a[keyi], &a[prev]);
//	return prev;
//}
//
快速排序
//void QuickSort(PepInfo* a, int left, int right)
//{
//	//如果left>right,區(qū)間不存在
//	//left==right,只有一個(gè)元素,可以看成是有序的
//	if (left >= right)
//	{
//		return;
//	}
//	else
//	{
//		//單次排序
//		int keyi = partion3(a, left, right);
//		//分成左右區(qū)間,排序左右區(qū)間
//		QuickSort(a, left, keyi - 1);
//		QuickSort(a, keyi + 1, right);
//	}
//}
//
 鏈表快速排序函數(shù)
//void sortList(Node* phead) 
//{
//	// 處理空或單節(jié)點(diǎn)鏈表的情況
//	if (!phead || !phead->next)
//	{
//		return;
//	}
//
//	//求鏈表長(zhǎng)度
//	int len = 0;
//	Node* cur = phead;
//	while (cur) 
//	{
//		len++;
//		cur = cur->next;
//	}
//
//	// 將鏈表轉(zhuǎn)換為數(shù)組
//	PepInfo* arr = malloc(len * sizeof(PepInfo));
//	if (arr == NULL)
//	{
//		printf("malloc error\n");
//		exit(-1);
//	}
//	cur = phead;
//	for (int i = 0; i < len; i++) 
//	{
//		arr[i] = cur->data;
//		cur = cur->next;
//	}
//
//	// 快速排序
//	QuickSort(arr, 0, len - 1);
//
//	// 將數(shù)組轉(zhuǎn)換為鏈表
//	cur = phead;
//	for (int i = 0; i < len; i++) 
//	{
//		cur->data = arr[i];
//		cur = cur->next;
//	}
//
//	free(arr);
//}

//交換數(shù)據(jù)
void swap(Node* p1, Node* p2)
{
	struct PepInfo tmp = p1->data;
	p1->data = p2->data;
	p2->data = tmp;
}

//進(jìn)行排序
void sort(Node* phead)
{
	//空不排序
	assert(phead != NULL);

	Node* begin = phead;
	Node* end = phead->next;
	while (end)
	{
		while (begin != end)
		{
			if (begin->data.age > end->data.age)
			{
				swap(begin,end);
			}
			begin = begin->next;
		}
		end = end->next;
		begin = phead;
	}
}


//已有數(shù)據(jù)讀取,可能要更改頭指針,傳二級(jí)指針修改一級(jí)指針
void StartFileEntry(Node** pphead)
{
	FILE* pf = fopen("data.txt", "rb");
	if (pf == NULL)
	{
		printf("打開(kāi)文件失敗\n");
		exit(-1);
	}

	//保存讀取到的數(shù)據(jù)
	PepInfo* tmp = (PepInfo*)malloc(sizeof(PepInfo));
	if (tmp == NULL)
	{
		printf("malloc error\n");
		exit(-1);
	}
	//先讀取一次
	fread(tmp, sizeof(PepInfo), 1, pf);
	//保存尾部節(jié)點(diǎn)地址
	Node* tail = NULL;
	
	//讀取到結(jié)尾時(shí)feof()返回0,未讀取到結(jié)尾返回非0值
	while (!feof(pf))
	{
		//生成新節(jié)點(diǎn)
		Node* NewNode = (Node*)malloc(sizeof(Node));
		if (NewNode == NULL)
		{
			printf("malloc error\n");
			exit(-1);
		}
		NewNode->data = *tmp;
		NewNode->next = NULL;
		//第一次頭為空,更新
		if (*pphead == NULL)
		{
			*pphead = NewNode;
			tail = *pphead;
		}
		//頭不為空,新節(jié)點(diǎn)鏈接到尾后面,尾指針更新
		else
		{
			tail->next = NewNode;
			tail = tail->next;
		}
		//繼續(xù)讀取
		fread(tmp, sizeof(PepInfo), 1, pf);
	}
	fclose(pf);
}


//新數(shù)據(jù)錄入
void UpdateFileEntry(Node* phead)
{
	FILE* pf = fopen("data.txt", "wb");
	if (phead == NULL)
	{
		return;
	}
	else
	{
		while (phead)
		{
			fwrite(&(phead->data), sizeof(PepInfo), 1, pf);
			phead = phead->next;
		}
	}
	fclose(pf);
}

test.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("***** 0.退出              ******\n");
	printf("********************************\n");

}

int main()
{
	Node* head = NULL;
	int input = 0;

	//原信息錄入,這里用讀模式打開(kāi),第一次需要手動(dòng)創(chuàng)建文件
	StartFileEntry(&head);
	do
	{
		menu();
		printf("請(qǐng)選擇:>");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			AddContact(&head);
			printf("增加成功\n");
			break;
		case 2:
			DelContact(&head);
			break;
		case 3:
		{
			char name[max_name];
			printf("請(qǐng)輸入要查找聯(lián)系人的名字:");
			scanf("%s", name);
			Node* pos = FindContact(head, name);
			if (pos == NULL)
			{
				printf("查找失敗\n");
			}
			else
			{
				printf("找到了\n");
				printf("%-20s\t%-5d\t%-5s\t%-20s\t%-20s\n",
					pos->data.name, pos->data.age, pos->data.sex,
					pos->data.tele, pos->data.addr);
			}
			break;
		}
		case 4:
			ModifyContact(head);
			break;
		case 5:
			sort(head);
			printf("排序成功\n");
			break;
		case 6:
			PrintContact(head);
			break;
		case 0:
			printf("退出\n");
			break;
		default:
			printf("非法輸入,重新輸入\n");
			break;
		}
	} while (input);

	//新信息錄入
	UpdateFileEntry(head);
	return 0;
}

到了這里,關(guān)于動(dòng)態(tài)通訊錄實(shí)現(xiàn)(C語(yǔ)言)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 【C語(yǔ)言】實(shí)現(xiàn)動(dòng)態(tài)版通訊錄

    【C語(yǔ)言】實(shí)現(xiàn)動(dòng)態(tài)版通訊錄

    ??內(nèi)容專欄:【C語(yǔ)言】進(jìn)階部分 ??本文概括: 結(jié)合自定義類型、動(dòng)態(tài)內(nèi)存管理知識(shí),對(duì)靜態(tài)版本的通訊錄進(jìn)行優(yōu)化。 ??本文作者:花 碟 ??發(fā)布時(shí)間:2023.4.2 ? 目錄 前言: 一、靜態(tài)版本代碼實(shí)現(xiàn): 二、動(dòng)態(tài)通訊錄? 三、代碼整理? 前面我們學(xué)過(guò)了結(jié)構(gòu)體、枚舉等自定義

    2024年02月02日
    瀏覽(96)
  • C語(yǔ)言動(dòng)態(tài)內(nèi)存練習(xí):【通訊錄(動(dòng)態(tài)內(nèi)存版本)實(shí)現(xiàn)】

    前面我們寫(xiě)了一個(gè)靜態(tài)數(shù)組版本的通訊錄,再結(jié)合剛學(xué)習(xí)的動(dòng)態(tài)內(nèi)存管理的知識(shí),我們現(xiàn)在來(lái)實(shí)現(xiàn)一個(gè)動(dòng)態(tài)內(nèi)存版本的通訊錄。 動(dòng)態(tài)內(nèi)存版本的通訊錄,主要還是為了解決靜態(tài)數(shù)組版本的通訊錄空間太大導(dǎo)致的內(nèi)存浪費(fèi)和空間太小不夠存放的問(wèn)題。 擴(kuò)容策略: 為通訊錄設(shè)置

    2023年04月13日
    瀏覽(35)
  • C語(yǔ)言之通訊錄的實(shí)現(xiàn)(靜態(tài)版,動(dòng)態(tài)版,文件版)

    C語(yǔ)言之通訊錄的實(shí)現(xiàn)(靜態(tài)版,動(dòng)態(tài)版,文件版)

    個(gè)人主頁(yè)(找往期文章包括但不限于本期文章中不懂的知識(shí)點(diǎn)):?我要學(xué)編程(?_?)-CSDN博客 目錄 靜態(tài)通訊錄的實(shí)現(xiàn)邏輯? test.c:通訊錄的邏輯實(shí)現(xiàn) Contact.h:函數(shù)的聲明與頭文件的包含 Contact.c:函數(shù)的實(shí)現(xiàn)? 通訊錄源碼:? test.c: Contact.c: Contect.h: 動(dòng)態(tài)版通訊錄? test.c: Co

    2024年04月13日
    瀏覽(57)
  • 【進(jìn)階C語(yǔ)言】動(dòng)態(tài)版通訊錄的實(shí)現(xiàn)(詳細(xì)講解+全部碼源)

    【進(jìn)階C語(yǔ)言】動(dòng)態(tài)版通訊錄的實(shí)現(xiàn)(詳細(xì)講解+全部碼源)

    前言 ??作者簡(jiǎn)介: 熱愛(ài)跑步的恒川 ,致力于 C/C++、Java、Python 等多編程語(yǔ)言,熱愛(ài)跑步,喜愛(ài)音樂(lè)的一位博主。 ??本文收錄于 C語(yǔ)言進(jìn)階 系列,本專欄主要內(nèi)容為數(shù)據(jù)的存儲(chǔ)、指針的進(jìn)階、字符串和內(nèi)存函數(shù)的介紹、自定義類型結(jié)構(gòu)、動(dòng)態(tài)內(nèi)存管理、文件操作等,持續(xù)更

    2024年02月01日
    瀏覽(22)
  • 動(dòng)態(tài)內(nèi)存管理函數(shù)介紹及C語(yǔ)言實(shí)現(xiàn)通訊錄管理系統(tǒng)2.0版(動(dòng)態(tài)增長(zhǎng)版本)

    動(dòng)態(tài)內(nèi)存管理函數(shù)介紹及C語(yǔ)言實(shí)現(xiàn)通訊錄管理系統(tǒng)2.0版(動(dòng)態(tài)增長(zhǎng)版本)

    之前向大家介紹了C語(yǔ)言實(shí)現(xiàn)通訊錄管理系統(tǒng)1.0版本,但該版本有明顯的不足之處,比如:一開(kāi)始就開(kāi)辟了1000個(gè)date數(shù)組,如果聯(lián)系人很少,那么就會(huì)造成嚴(yán)重的內(nèi)存浪費(fèi),或者聯(lián)系人超過(guò)了1000人,那么原數(shù)組就放不下了,所以今天我們考慮使用動(dòng)態(tài)內(nèi)存管理的辦法來(lái)實(shí)現(xiàn)一個(gè)

    2023年04月08日
    瀏覽(21)
  • 【C語(yǔ)言】動(dòng)態(tài)通訊錄 -- 詳解

    【C語(yǔ)言】動(dòng)態(tài)通訊錄 -- 詳解

    前面詳細(xì)介紹了靜態(tài)版通訊錄【C語(yǔ)言】靜態(tài)通訊錄 -- 詳解_炫酷的伊莉娜的博客-CSDN博客,但是靜態(tài)版通訊錄的空間是無(wú)法被改變的,而且空間利用率也不高。為了解決靜態(tài)通訊錄這一缺點(diǎn),這時(shí)就要有一個(gè)能夠隨著存入聯(lián)系人數(shù)量的增加而增大空間的通訊錄。接下來(lái)我們將

    2024年02月12日
    瀏覽(20)
  • 【C語(yǔ)言】動(dòng)態(tài)通訊錄(超詳細(xì))

    【C語(yǔ)言】動(dòng)態(tài)通訊錄(超詳細(xì))

    通訊錄是一個(gè)可以很好鍛煉我們對(duì)結(jié)構(gòu)體的使用,加深對(duì)結(jié)構(gòu)體的理解,在為以后學(xué)習(xí)數(shù)據(jù)結(jié)構(gòu)打下結(jié)實(shí)的基礎(chǔ) 這里我們想設(shè)計(jì)一個(gè)有 添加聯(lián)系人,刪除聯(lián)系人,查找聯(lián)系人,修改聯(lián)系人,展示聯(lián)系人,排序 這幾種功能的通訊錄 注意:我們按照三個(gè)區(qū)域劃分 上圖所示進(jìn)行

    2024年02月08日
    瀏覽(23)
  • C語(yǔ)言實(shí)踐——通訊錄(2)(動(dòng)態(tài)版)

    首先感謝上一篇博客的大佬們的點(diǎn)贊,非常感謝?。?! 目錄 前言 ?一、需要添加的功能 1. 初始化——?jiǎng)討B(tài)內(nèi)存開(kāi)辟 2.添加聯(lián)系人——通訊錄擴(kuò)容 3.退出通訊錄——通訊錄銷毀 二、具體操作 1.鋪墊 2.修改初始化函數(shù) 3.修改添加函數(shù)? 4.退出通訊錄,新增銷毀函數(shù) 上一篇文章我

    2023年04月08日
    瀏覽(32)
  • 【C語(yǔ)言實(shí)戰(zhàn)項(xiàng)目】通訊錄(動(dòng)態(tài)增容版)

    【C語(yǔ)言實(shí)戰(zhàn)項(xiàng)目】通訊錄(動(dòng)態(tài)增容版)

    ?? 個(gè)人主頁(yè) :修修修也 ?? 所屬專欄 :數(shù)據(jù)結(jié)構(gòu) ?? 操作環(huán)境 : Visual Studio 2022 目錄 一.動(dòng)態(tài)增容版簡(jiǎn)介 二.動(dòng)態(tài)增容版逐步實(shí)現(xiàn)詳解 1.創(chuàng)建通訊錄 2. 初始化通訊錄 3.增加聯(lián)系人 4.通訊錄增容 5.銷毀通訊錄 三.動(dòng)態(tài)增容版代碼整合 contact.c test.c contact.h 上篇博客我們一起用C語(yǔ)言

    2024年02月11日
    瀏覽(20)
  • 動(dòng)態(tài)通訊錄——C語(yǔ)言【詳解+全部碼源】

    動(dòng)態(tài)通訊錄——C語(yǔ)言【詳解+全部碼源】

    作者簡(jiǎn)介: 辭七七,目前大一,正在學(xué)習(xí)C/C++,Java,Python等 作者主頁(yè): 七七的個(gè)人主頁(yè) 文章收錄專欄: 進(jìn)階C語(yǔ)言,本專欄主要講解數(shù)據(jù)存儲(chǔ),進(jìn)階指針,動(dòng)態(tài)內(nèi)存管理,文件操作,程序環(huán)境和預(yù)處理等 歡迎大家點(diǎn)贊 ?? 收藏 ? 加關(guān)注哦!???? 我們之前以及寫(xiě)過(guò)靜態(tài)版

    2023年04月21日
    瀏覽(24)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包