主頁 > 軟體設計 > C語言順序表實作動態通訊錄,并將通訊錄檔案儲存在二進制檔案中(手把手教學除錯,小白入)

C語言順序表實作動態通訊錄,并將通訊錄檔案儲存在二進制檔案中(手把手教學除錯,小白入)

2021-04-02 11:27:32 軟體設計

文章目錄

    • 前言與生成結果
    • 1.具體代碼實作(生成通訊錄,添加資訊并查重,列印通訊錄人的資訊)
    • 第一階段測驗
    • 2.具體代碼實作(通訊錄資訊查找,通訊錄人資訊的修改,動態通訊錄記憶體Free)
    • 第二階段除錯
    • 3.具體代碼實作(排序通訊錄人的資訊)
    • 第三階段除錯
    • 4.整體代碼框架的構建
    • 5.具體代碼實作(保存通訊錄資訊,加載通訊錄,洗掉通訊錄的人或整體的資訊)
    • 最后階段除錯!!!
    • 6.全部代碼付下
    • 7.小結

前言與生成結果

在這里插入圖片描述

在這里插入圖片描述

加載通訊錄表示將二進制檔案的資料匯入結構體中,

初始化通訊錄成功表示:成功的開辟了一塊動態的空間,

可以實作增刪查找,全部清空通訊錄,查重,保存功能,

在這里插入圖片描述
在保存后會自動在桌面生成一個通訊錄文本,

1.具體代碼實作(生成通訊錄,添加資訊并查重,列印通訊錄人的資訊)

先考慮頭檔案

首先我們要宣告一個人的結構體

#define MAX_NAME 20

#define MAX_SEX 5

#define MAX_TELE 20

#define MAX_ADDRESS 20

#define MAX_CAP 3

typedef struct people
{
	char name[MAX_NAME];//姓名
	int age;//年齡
	char sex[MAX_SEX];//性別
	char tele[MAX_TELE];//電話
	char address[MAX_ADDRESS];//地址
}people;

之后我們還要定義一個通訊錄結構體

typedef struct contect
{
	int sz;//當前通訊錄人數
	people* data;//動態開辟的空間地址
	int capacity;//最大容量
}contect;

注意:

如果有一個通訊錄結構體指標p,

p->有3種情況.

1.int sz;
2.int capacity;
3.一塊連續空間的地址,地址中放的都是people結構體的資料

所以我們可以知道
p->data[p->sz]與p->*(data+sz)相同找到了下標為sz的people結構體
具體陣列與指標的關系見
陣列與指標的關系

所以p->data[p->sz] . 就可以找到sz位置上的結構體上的不同資訊

在之后我們要列印一個選單,讓人可以選擇

void menu();

類似這樣
在這里插入圖片描述
通過選擇不同的數字,執行不同的函式,

之后還要實作初始化 增刪,列印通訊錄的功能

void initcontect(contect* p);

void Addcontect(contect* p);

void Showcontect(contect* p);

在這里插入圖片描述

我們不急去想接下來的功能,先把這些介面寫好,在.c檔案中寫下函式的實作

選單的列印沒什么好說的

void menu()
{
	printf("|-----------------------|\n");
	printf("|        contact        |\n");
	printf("|   1.Add     2.Delete  |\n");
	printf("|   3.Search  4.Modify  |\n");
	printf("|   5.Show    6.Sort    |\n");
	printf("|        0.Exit         |\n");
	printf("|-----------------------|\n");
}

初始化通訊錄結構體

void initcontect(contect* p)
{
	p->sz = 0;//起始資料為0
	p->capacity = MAX_CAP;//之前宏定義過容量
	p->data = (people*)malloc(3*sizeof(people));
	//動態開辟一塊大小為3個people結構體大小的空間
	if (p->data == NULL)
	{
		printf("通訊錄初始化失敗,請退出程式重試\n");
		exit(1);
	}
}

添加一個人的資訊

注意:

在添加人之后還要查重,萬一這個人我們之前就已經記錄過,就沒有必要在儲存她的資訊了,

所以我們要一個查重函式,和一個洗掉函式,檢查已有人的名字,當有相同的名字時,再自動把這個人刪掉,而姓名是字串strcmp()在遇到相同的字符時回傳非零值,所以可以用strcmp來實作

void Addcontect(contect* p)
{
	int pos = -1;
	if (p->sz == p->capacity)
	//當現在的通訊錄人=最大容量時再次呼叫增加函式時增容
	{
		people* ptr =
 (people*)realloc(p->data, (p->capacity + 2) * sizeof(people));
 //每次增容2個people,也可以增加不同值,
		if (ptr==NULL)
		{
			printf("記憶體不足,增容失敗\n");
		}
		else
		{
			p->data = ptr;
		//realloc增容通訊錄結構體地址可能改變,
		//詳情見realloc函式所以要重新獲得地址
			p->capacity += 2;//增容后總大小增大,
			printf("提示:通訊錄增容成功\n");

		}
	}//儲存人的資訊
		printf("請輸入姓名:>\n");
		scanf("%s",p->data[p->sz].name);
		printf("請輸入年齡:>\n");
		scanf("%d",&p->data[p->sz].age);
		printf("請輸入性別:>\n");
		scanf("%s",p->data[p->sz].sex);
		printf("請輸入電話:>\n");
		scanf("%s",p->data[p->sz].tele);
		printf("請輸入地址:>\n");
		scanf("%s",p->data[p->sz].address);
		p->sz++;//儲存成功后現有大小加1
		system("cls");
		
		pos = search_name2(p->data[p->sz-1].name, p);
		//當search_name2函式回傳-1,表示沒有重名
		//當search_name2 回傳其他值表示重名
		if (pos == -1)
		{
			printf("添加成功\n");
		}
		else
		{
	//發現重名,提示一下再自動把剛添加的人的資訊刪掉
			printf("通訊錄中已經有此人\n");
			dele_name2(p->sz,p);//洗掉函式
			p->sz--;//大小-1
		}
}
int search_name2(char name[], contect* ps)
{
	for (int i = 0; i < ps->sz-1; i++)
	{
		if (strcmp(name, ps->data[i].name) == 0)
		{
			return i;//有重名回傳非0值
		}
	}
	return -1;
}
void dele_name2(int p,contect* ps)
{
	ps->data[p - 1] = ps->data[p];
	//直接將要洗掉的位置后一位隨機值資料放在這一位,
	//其實也可以不寫,直接將記錄當前通訊錄人數的size減少1就行,
}
void Showcontect(contect* p)
{
	if (p->sz == 0)
	{
		system("cls");
		printf("通訊錄為空\n");//當通訊錄為空時直接不列印
	} 
	else
	{
		system("cls");
		printf("%-15s\t %-5s\t %-5s\t %-12s\t %-20s\t\n",
		//控制通訊錄的列印形式
		 "姓名","年齡","性別","電話","地址");
		for (int i = 0; i < p->sz; i++)
		{
			printf("%-15s\t %-5d\t %-5s\t %-12s\t %-20s\t\n",
			p->data[i].name,
			p->data[i].age,p->data[i].sex,
			p->data[i].tele,p->data[i].address);
		}

	}
}

第一階段測驗

寫到這里我們先開始測驗我們的代碼

把我們剛寫的函式再添加到頭檔案中

#pragma once//防止重復包含頭檔案
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

#define MAX_NAME 20

#define MAX_SEX 5

#define MAX_TELE 20

#define MAX_ADDRESS 20

#define MAX_CAP 3

typedef struct people
{
	char name[MAX_NAME];//姓名
	int age;//年齡
	char sex[MAX_SEX];//性別
	char tele[MAX_TELE];//電話
	char address[MAX_ADDRESS];//地址
}people;

typedef struct contect
{
	int sz;//當前通訊錄人數
	people* data;//動態開辟的空間地址
	int capacity;//最大容量
}contect;

void menu();

void initcontect(contect* p);

void Addcontect(contect* p);

void Showcontect(contect* p);

void dele_name2(int p, contect* ps);

int search_name2(char name[], contect* ps);

在main函式中寫下測驗介面

#include"標頭.h"//包含自己寫的頭檔案

int main()
{
	contect con;//生成通訊錄
	initcontect(&con);//初始化通訊錄;
	Addcontect(&con);//添加通訊錄;
	Addcontect(&con);//添加通訊錄;
	Addcontect(&con);//添加通訊錄;
	Addcontect(&con);//添加通訊錄;
	Showcontect(&con);//列印通訊錄

	return 0;
}

在這里插入圖片描述
初始化通訊錄介面:
在這里插入圖片描述
初始化成功
在這里插入圖片描述
添加資訊介面:
在這里插入圖片描述
在這里插入圖片描述

再輸入相同的人的名字檢查,查重介面:

在這里插入圖片描述
再添加3個不同人的資訊來檢查增容介面:

在這里插入圖片描述

之后進入列印函式介面

在這里插入圖片描述

在這里插入圖片描述
清屏列印,沒有問題

之后我們就可以考慮接下來的功能了

2.具體代碼實作(通訊錄資訊查找,通訊錄人資訊的修改,動態通訊錄記憶體Free)

光有這些功能還不能稱為通訊錄

我們還要實作查找通訊錄人的功能,還要實作修改人資訊的功能,

修改人的資訊首先要查找到這個人的資訊所以我們先寫查找函式,

查找函式其實我們已經在之前寫過了,原理為之前的查重函式,只不過對找到的資訊處理不同而已,之前寫查重函式,找到相同的名字進行洗掉,查找函式找到相同函式進行列印,

其次查找函式還可以選擇通過名字查找,也可以選擇通過電話查找,我們再給它寫一個選單,

要新加兩個函式,一個是選單函式,一個是電話查找函式

void Searchcontect(contect*ps)
{
	char name[20] = { 0 };
	char tele[20] = { 0 };
	int input = 0;
	int pos = 0;
	system("cls");
	do
	{
		menu_search();
		scanf("%d",&input);
		switch (input)
		{
		case 1:
			system("cls");
			printf("請輸入你要查找人的名字\n");
			scanf("%s",name);
			 pos = search_name2(name, ps);
			if (pos == -1)
			{
				printf("你要找的名字不存在\n");
			}
			else
			{
				printf("%-15s\t%-4s\t%-5s\t%-12s\t%-20s\n",
				 "姓名", "年齡", "性別", "電話", "住址");
				printf("%-15s\t%-4d\t%-5s\t%-12s\t%-20s\n",
					ps->data[pos].name,
					ps->data[pos].age,
					ps->data[pos].sex,
					ps->data[pos].tele,
					ps->data[pos].address);
			}
			printf("\n");
			printf("\n");
			break;
		case 2:
			system("cls");
			printf("請輸入你要查找人的電話號碼\n");
			scanf("%s",tele);
			 pos = search_tele(tele, ps);
			if (pos == -1)
			{
				printf("你要查找的電話號碼不存在\n");
			}
			else
			{
				printf("%-15s\t%-4s\t%-5s\t%-12s\t%-20s\n",
				 "姓名", "年齡", "性別", "電話", "住址");
				printf("%-15s\t%-4d\t%-5s\t%-12s\t%-20s\n",
					ps->data[pos].name,
					ps->data[pos].age,
					ps->data[pos].sex,
					ps->data[pos].tele,
					ps->data[pos].address);
			}
			printf("\n");
			printf("\n");
			break;
		case 0:
			system("cls");
			printf("回傳成功\n");
			break;
		default:
			system("cls");
			printf("選擇錯誤,請重新選擇\n");
			break;
		}
	} while (input);
}

選單函式:

void menu_search()
{
	printf("****1.通過名字查找****\n");
	printf("****2.通過電話查找****\n");
	printf("*****0.回傳上一步*****\n");
	//回傳主函式的一個回圈相當于回傳
}

這里電話查找本質是字串,所以原理與名字查找相同:

找到相同的字串回傳非零,找不到字串回傳-1.

int search_tele(char tele[], contect* ps)
{
	for (int i = 0; i < ps->sz; i++)
	{
		if (strcmp(tele, ps->data[i].tele) == 0)
		{
			return i;
		}
	}
	return -1;
}

再把我們新寫的函式加到頭檔案中
在這里插入圖片描述
之后我們再實作修改人資訊函式:

修改的時候我們先要查找人的資訊,如果找不到這個人就提示一下,找到了我們要選擇要修改的資訊

之后同樣,我們要給一個選單,選擇你要修改什么資訊

類似于

在這里插入圖片描述

在這里插入圖片描述

在這里插入圖片描述
這里回傳上一步回傳到了輸入修改人的名字這一步,

查找函式選單;

void menu_modify()
{
	printf("****1.通過名字查找****\n");
	printf("****2.通過電話查找****\n");
	printf("*****0.回傳上一步*****\n");
}

修改選單函式:

void menu_modify_option()
{
	printf("****1.修改姓名****\n");
	printf("****2.修改年齡****\n");
	printf("****3.修改性別****\n");
	printf("****4.修改電話****\n");
	printf("****5.修改地址****\n");
	printf("***0.回傳上一步***\n");
}

具體實作將用到兩個switch嵌套,

void Modifycontect(contect* ps)
{
	char name[MAX_NAME] = { 0 };
	char tele[MAX_TELE] = { 0 };
	int pos = 0;
	int input = 0;
	do
	{
		menu_modify();//查找選單
		scanf("%d",&input);
		switch (input)
		{
		case 1://通過名字查找人
			system("cls");
			printf("請輸入你要修改人的名字\n");
			scanf("%s", name);
			pos = search_name2(name, ps);//第一階段寫過的查找名字函式
			if (pos == -1)
			{
				printf("要修改的人不存在,請確定通訊錄資訊\n");
				int i = 0;
				printf("\n");
				printf("是否需要回傳選單確認資訊 1.回傳 2.重新尋找\n");
				scanf("%d",&i);
				if(i == 1)
				{
					return;//回到主函式的switch中
				}
			}
			else
			{
				int input2 = 0;
				do
				{
					menu_modify_option();
					scanf("%d",&input2);
					switch (input2)
					{
					case 1:
						printf("你要將原來的名字修改為\n");
						scanf("%s",ps->data[pos].name);
						system("cls");
						break;
					case 2:
						printf("你要將原來的年齡改為\n");
						scanf("%d",&ps->data[pos].age);
						system("cls");
						break;
					case 3:
						printf("你要將原來的性別改為\n");
						scanf("%s",ps->data[pos].sex);
						system("cls");
						break;
					case 4:
						printf("你要將原來的電話改為\n");
						scanf("%s",ps->data[pos].tele);
						system("cls");
						break;
					case 5:
						printf("你要將原來的地址改為\n");
						scanf("%s",ps->data[pos].address);
						system("cls");
						break;
					case 0:
						system("cls");
						printf("回傳成功\n");
						break;
					default:
						system("cls");
						printf("輸入錯誤,請重新輸入\n");
						break;
					}
				} while (input2);
			}
			break;
		case 2://通過電話查找人
			system("cls");
			printf("請輸入你要修改人的電話號碼\n");
			scanf("%s", tele);
			pos = search_tele(tele, ps);//前面實作過此函式
			if (pos == -1)
			{
				printf("要修改的人不存在,請確定通訊錄資訊\n");
				int i = 0;
				printf("\n");
				printf("是否需要回傳選單確認資訊 1.回傳 2.重新尋找\n");
				scanf("%d", &i);
				if (i == 1)
				{
					return;
				}
			}
			else
			{
				int input2 = 0;
				do
				{
					menu_modify_option();
					scanf("%d", &input2);
					switch (input2)
					{
					case 1:
						printf("你要將原來的名字修改為\n");
						scanf("%s", ps->data[pos].name);
						system("cls");
						break;
					case 2:
						printf("你要將原來的年齡改為\n");
						scanf("%d", &ps->data[pos].age);
						system("cls");
						break;
					case 3:
						printf("你要將原來的性別改為\n");
						scanf("%s", ps->data[pos].sex);
						system("cls");
						break;
					case 4:
						printf("你要將原來的電話改為\n");
						scanf("%s", ps->data[pos].tele);
						system("cls");
						break;
					case 5:
						printf("你要將原來的地址改為\n");
						scanf("%s", ps->data[pos].address);
						system("cls");
						break;
					case 0:
						system("cls");
						printf("回傳成功\n");
						break;
					default:
						system("cls");
						printf("輸入錯誤,請重新輸入\n");
						break;
					}
				} while (input2);
			}
			break;
		case 0:
			system("cls");
			printf("回傳成功\n");
			break;
		default:
			system("cls");
			printf("選擇錯誤,請重新選擇\n");
			break;
		}

	} while (input);
}

因為我們動態通訊錄空間是malloc的就自然而然想到Free防止記憶體泄漏

void Deletinformation(contect* p)
{
	free(p->data);//釋放空間
	p->data= NULL;//指標指空
	p->sz = 0;//通訊錄現有大小為0;
}

寫完后我們將函式放在頭檔案宣告一下我們寫過的函式:

在這里插入圖片描述

第二階段除錯

在main函式中添加

#include"標頭.h"//包含你寫的頭檔案名字!!!

int main()
{
	contect con;//生成通訊錄;
	initcontect(&con);//初始化通訊錄;
	Addcontect(&con);//添加通訊錄;
	Addcontect(&con);//添加通訊錄;
	Searchcontect(&con);//查找已經存在的人;
	Searchcontect(&con);//查找不存在的人;
	Modifycontect(&con);//修改不存在的人;
	Modifycontect(&con);//修改存在人的姓名;
	Showcontect(&con);//列印修改后的通訊錄;
	Modifycontect(&con);//修改存在人的地址;
	Showcontect(&con);
	//類似測驗修改的其他功能是否正常
	Deletinformation(&con);
	return 0;
}

在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述
查找介面沒有問題,

在這里插入圖片描述
在這里插入圖片描述
修改不存在人正常

在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述
修改之后的資訊,修改介面正常
在這里插入圖片描述

在這里插入圖片描述
銷毀通訊錄介面正常

至此我們通訊錄都可以正常作業,

3.具體代碼實作(排序通訊錄人的資訊)

我們在實作了通訊錄的增加,修改,查找,查重功能后,我們還想要排序一下通訊錄人的資訊,這里選擇用qsort排序

void Sortcontect(contect* ps)
{
	qsort(ps->data,ps->sz,sizeof(people), CmpByName);
//要排序data空間,排序大小,每一個資料的大小是結構體people大小,函式指標
	system("cls");
	printf("排序成功\n");
}

這里要寫一個函式指標,也是非常簡單

int CmpByName(const void* e1, const void* e2)
{
	return strcmp((const char*)e1, (const char*)e2);
}

qsort函式的用法

在頭檔案包含一下寫的排序函式

在這里插入圖片描述

第三階段除錯

在main函式中

#include"標頭.h"//包含自己的頭檔案!!!!

int main()
{
	contect con;//生成通訊錄;
	initcontect(&con);//初始化通訊錄;
	Addcontect(&con);//添加通訊錄;
	Addcontect(&con);//添加通訊錄;
	Addcontect(&con);//添加通訊錄;
	 Showcontect(&con);//列印添加前的通訊錄
	Sortcontect(&con);//排序
	 Showcontect(&con);//列印排序后的通訊錄
	Deletinformation(&con);//釋放記憶體
	return 0;
}

排序前:
在這里插入圖片描述
在這里插入圖片描述
排序后:
在這里插入圖片描述
排序介面完成

4.整體代碼框架的構建

通訊錄的功能大體實作了,這里我們大體構建一下通訊錄資訊的基本框架

并且選擇不同數字對應不同的介面

為了方便我們書寫代碼,這里在頭檔案中定義列舉型別,

enum option
{
	Exit,//數值為0對應選單中的0退出
	Add,//1
	Delete,//2
	Search,//3
	Modify,//4
	Show,//5
	Sort,//6
	Save,//7
};

在main函式中

int main()
{
	int input = 0;
	int input2 = 0;
	contect con;//創建通訊錄
	initcontect(&con);//初始化通訊錄
	do//回圈執行介面,直到輸入0時退出
	{
		menu();//列印基本選單
		scanf("%d",&input);
//因為主函式是一個switch句
//所以之前設計的函式回傳上一步選項都會回到主函式這里,不在贅述
		switch (input)
		{
		case Add://Add數值大小為1
			Addcontect(&con);//加法介面
			break;
		case Delete:
			Deletecontect(&con);//洗掉介面,我們目前沒有寫
			break;
		case Search:
			Searchcontect(&con);//查找介面
			break;
		case Modify:
			Modifycontect(&con);//修改介面
			break;
		case Show:
			Showcontect(&con);//列印介面
			break;
		case Sort:
			Sortcontect(&con);//排序介面
			break;
		case Save:
			Savecontect(&con);//保存介面,我們目前沒有寫
			system("cls");
			printf("保存成功\n");
			break;
		case Exit://退出
			system("cls");
			printf("退出通訊錄后,如不保存資料會丟失,請先保存再退出\n");//提示用戶保存
			printf("1.退出     0.取消退出\n");
			scanf("%d",&input2);
			if (input2 == 0)
			{
				system("cls");
				input = 1;//如果取消退出了把input改成非零就行
				printf("取消退出成功\n");
			}
			else
			{
				Deletinformation(&con);//繼續退出的話銷毀申請的空間
				system("cls");
				printf("退出通訊錄成功\n");
			}
			break;
		default:
			system("cls");
			printf("選擇錯誤,請重新選擇\n");
			break;
		}
	} while (input);
	return 0;
}

5.具體代碼實作(保存通訊錄資訊,加載通訊錄,洗掉通訊錄的人或整體的資訊)

我們首先來實作保存通訊錄功能,

void Savecontect(contect*ps)
{
	FILE* pf = fopen("contect.data", "wb");
	//以二進制的寫的形式打開contect.data檔案,
	//如果沒有此檔案,會自己自動創建
	if (pf == NULL)
	{
		printf("記憶體不足,保存失敗\n");
		return;
	}
	//用回圈的方式以二進制形式寫入pf檔案指標指向的檔案
	for (int i = 0; i < ps->sz; i++)
	{
	//這四個引數分別為
	//要寫資料的地址,每一個資料的大小,每次寫幾個資料,寫到檔案
		fwrite(&(ps->data[i]),sizeof(people),1,pf);
	}
	fclose(pf);//關閉檔案
	pf = NULL;//檔案指標置空
	printf("保存成功\n");
}

那么我們保存到檔案中的資訊在下次打開通訊錄的時候要加載,所以我們要對初始化通訊錄函式做調整

先寫出加載函式

加載時要判斷是否要擴容

void LodeContact(contect* p)
{
	FILE* pf = fopen("contect.data", "rb");
	//以二進制讀的方式打開檔案contect.data
	//如果沒有此檔案會回傳空指標
	if (pf == NULL)
	{
		printf("加載通訊錄失敗\n");
		//說明沒有這個檔案,沒有資料可以加載
		return;
	}
//創建一個臨時的people結構體變數
//將檔案的一個資料先放到臨時的變數中
	people tmp = {0};
	//fread函式會回傳讀取的讀取資料的個數
	//所以用while回圈每次讀取一個people結構體
	//當讀取不到資料的時候回傳0,停止回圈,
//fread函式的引數為
//讀到的資料放到哪里,每一個資料的大小,一次讀幾個資料,從哪里讀
	while (fread(&tmp, sizeof(people), 1, pf))
	{
		CheckCapacity(p);//每一次都要檢查是否要擴容
		p->data[p->sz] = tmp;
	//把臨時的通訊錄資料放到,我們在main函式創建的通訊錄
		p->sz++;//通訊錄的大小增加1,
	}
	fclose(pf);//關閉檔案
	pf = NULL;//檔案指標置空
}

我們發現我們還要設計一個檢查是否要增容的函式

發現這個函式實作思想與我們寫的Addcontect(&con)函式相類似

void CheckCapacity(contect* p)
{
	if (p->sz == p->capacity)
	//如果現有的容量=最大大小下一次呼叫會擴容
	{
		people* ptr =
 (people*)realloc(p->data, (p->capacity + 2) * sizeof(people));
		if (ptr == NULL)
		{
			printf("記憶體不足,增容失敗\n");
		}
		else
		{
			p->data = ptr;
			p->capacity += 2;
			printf("提示:通訊錄增容成功\n");

		}
	}
}

之前我們也使用過這種檢查是否要擴容的片段可以寫成函式來減少代碼長度,

同時要修改初始化函式

void initcontect(contect* p)
{
	p->sz = 0;
	p->capacity = MAX_CAP;
	p->data = (people*)malloc(3*sizeof(people));
	if (p->data == NULL)
	{
		printf("通訊錄初始化失敗,請退出程式重試\n");
		exit(1);
	}
	LodeContact(p);//初始化成功后呼叫加載資訊函式
	printf("初始化通訊錄成功!\n");
}

最后我們來實作洗掉人資料的函式

洗掉要有兩種洗掉

1.洗掉一個人的資訊,
查找人的資訊,后再洗掉,同樣我們要給一個選單,
洗掉的原理是資料覆寫,并將表示通訊錄現有人數的size-1就行,

2.洗掉通訊錄整體所有人的資訊
洗掉所有人的資訊利用了 fopen函式
fopen函式以二進制寫的方式再一次打開時會洗掉之前檔案已經寫好的資訊,我們只要再free掉之前申請的空間,并且將記錄通訊錄大小的size改成0就ok了

代碼與之前的相同,不在贅述,

void Deletecontect(contect* p)
{
	int input = 0;
	int input2 = 0;
	int pos = 0;
	char  name[10] = { 0 };
	char tele[20] = { 0 };
	system("cls");
	do
	{
		menu_deleat();//列印洗掉的選單
		scanf("%d",&input);
		switch (input)
		{
		case 1:
			printf("請輸入你要洗掉的人名字\n");
			scanf("%s",name);
			pos= search_name2(name,p);
			if (pos == -1)
			{
				printf("要洗掉的名字不存在\n");
				printf("\n");
			}
			else
			{
				printf("洗掉成功\n");
				int j = 0;
				for (j = pos; j < p->sz - 1; j++)
				{
					p->data[pos] = p->data[pos + 1];
				}
				p->sz--;
			}

			break;
		case 2:
			printf("請輸入你要洗掉的人的電話號碼\n");
			scanf("%s", tele);
			pos = search_tele(tele, p);
			if (pos == -1)
			{
				printf("要洗掉的電話號碼不存在\n");
				printf("\n");
			}
			else
			{
				printf("洗掉成功\n");
				int j = 0;
				for(j = pos; j < p->sz - 1; j++)
				{
					p->data[pos] = p->data[pos + 1];
					//把后一個的值賦給前一個
				}
				p->sz--;
			}
			break;
		case 3:
			printf("你確定要全部洗掉通訊錄嗎? 1.確定 2.回到上一步\n");
			scanf("%d",&input2);
			if (input2 == 2);
			else
			{
				FILE* pf = fopen("contect.data", "wb");
				//再打開一次檔案但是不寫,相當于清空了檔案的內容
				Deletinformation(p);//釋放空間
				system("cls");
				return;
			}
			break;
		case 0:
			system("cls");
			printf("回傳成功\n");
			return;
			break;
		default:
			printf("選擇錯誤,請重新選擇\n");
			break;
		}
	} while (input);

}

列印洗掉選單

void menu_deleat()
{
	printf("****1.通過名字洗掉****\n");
	printf("****2.通過電話洗掉****\n");
	printf("*****  3.全部洗掉*****\n");
	printf("*****0.回傳上一步*****\n");
}

最后不要忘了在頭檔案宣告一下我們寫的函式,以及我們所宣告的列舉型別
在這里插入圖片描述

最后階段除錯!!!

因為之前的介面已經除錯過,只用檢查,保存,洗掉,加載介面即可
在這里插入圖片描述
開始因為沒有contect.data檔案所以顯示加載通訊錄失敗

在這里插入圖片描述

添加一個人的資訊并列印,

點擊保存生成一個contect檔案
在這里插入圖片描述

再關閉檔案后點開記事本已經存入資料

在這里插入圖片描述

在這里插入圖片描述

再點開生成的可執行程式,因為已經有了contect.data且有資料所以顯示初始化成功

直接列印通訊錄·的內容發現內容加載成功
在這里插入圖片描述
全部洗掉后,
在這里插入圖片描述
記事本變空
在這里插入圖片描述

至此,我們的通訊錄就寫完了,

6.全部代碼付下

save_contect.h

#define _CRT_SECURE_NO_WARNINGS 1//vs2019防止報錯

#define MAX_NAME 20

#define MAX_SEX 5

#define MAX_TELE 20

#define MAX_ADDRESS 20

//#define MAX 1000 //鎖定通訊錄大小為1000個

#define MAX_CAP 3

#include<stdio.h>

#include<windows.h>

#include<stdlib.h>

#include<string.h>

enum option
{
	Exit,
	Add,
	Delete,
	Search,
	Modify,
	Show,
	Sort,
	Save,
};

typedef struct people
{
	char name[MAX_NAME];
	int age;
	char sex[MAX_SEX];
	char tele[MAX_TELE];
	char address[MAX_ADDRESS];
}people;

typedef struct contect
{
	int sz;
	people* data;
	int capacity;
}contect;

void menu();

void initcontect(contect* p);

void Addcontect(contect* p);

void Showcontect(contect* p);

void Deletecontect(contect* p);

void menu_search();

int search_name(char name[], contect* ps);

int search_tele(char tele[], contect* ps);

int search_name2(char name[], contect* ps);

void dele_name2(int p,contect* ps); 

void Searchcontect(contect* ps);

void Modifycontect(contect* ps);

void menu_modify();

void menu_modify_option();

void Sortcontect(contect* ps);

int CmpByName(const void* e1, const void* e2);

void Deletinformation(contect*ps);

void Savecontect(contect*ps);

void CheckCapacity(contect* ps);

void LodeContact(contect* ps);

save_test.c

#define _CRT_SECURE_NO_WARNINGS 1

#include"save_contect.h"

int main()
{
	int input = 0;
	int input2 = 0;
	contect con;
	initcontect(&con);
	do
	{
		menu();
		scanf("%d",&input);
		switch (input)
		{
		case Add:
			Addcontect(&con);
			break;
		case Delete:
			Deletecontect(&con);
			break;
		case Search:
			Searchcontect(&con);
			break;
		case Modify:
			Modifycontect(&con);
			break;
		case Show:
			Showcontect(&con);
			break;
		case Sort:
			Sortcontect(&con);
			break;
		case Save:
			Savecontect(&con);
			system("cls");
			printf("保存成功\n");
			break;
		case Exit:
			system("cls");
			printf("退出通訊錄后,如不保存資料會丟失,請先保存再退出\n");
			printf("1.退出     0.取消退出\n");
			scanf("%d",&input2);
			if (input2 == 0)
			{
				system("cls");
				input = 1;
				printf("取消退出成功\n");
			}
			else
			{
				Deletinformation(&con);
				system("cls");
				printf("退出通訊錄成功\n");
			}
			break;
		default:
			system("cls");
			printf("選擇錯誤,請重新選擇\n");
			break;
		}
	} while (input);
	return 0;
}

save_contect.c

#define _CRT_SECURE_NO_WARNINGS 1

#include"save_contect.h"

void menu()
{
	printf("|-----------------------|\n");
	printf("|        contact        |\n");
	printf("|   1.Add     2.Delete  |\n");
	printf("|   3.Search  4.Modify  |\n");
	printf("|   5.Show    6.Sort    |\n");
	printf("|   0.Exit    7.Save    |\n");
	printf("|-----------------------|\n");
}

void menu_deleat()
{
	printf("****1.通過名字洗掉****\n");
	printf("****2.通過電話洗掉****\n");
	printf("*****  3.全部洗掉*****\n");
	printf("*****0.回傳上一步*****\n");
}

void menu_search()
{
	printf("****1.通過名字查找****\n");
	printf("****2.通過電話查找****\n");
	printf("*****0.回傳上一步*****\n");
}

void menu_modify()
{
	printf("****1.通過名字查找****\n");
	printf("****2.通過電話查找****\n");
	printf("*****0.回傳上一步*****\n");
}

void menu_modify_option()
{
	printf("****1.修改姓名****\n");
	printf("****2.修改年齡****\n");
	printf("****3.修改性別****\n");
	printf("****4.修改電話****\n");
	printf("****5.修改地址****\n");
	printf("***0.回傳上一步***\n");
}

void initcontect(contect* p)
{
	p->sz = 0;
	p->capacity = MAX_CAP;
	p->data = (people*)malloc(3*sizeof(people));
	if (p->data == NULL)
	{
		printf("通訊錄初始化失敗,請退出程式重試\n");
		exit(1);
	}
	LodeContact(p);
	printf("初始化通訊錄成功!\n");
}

void CheckCapacity(contect* p)
{
	if (p->sz == p->capacity)
	{
		people* ptr = (people*)realloc(p->data, (p->capacity + 2) * sizeof(people));
		if (ptr == NULL)
		{
			printf("記憶體不足,增容失敗\n");
		}
		else
		{
			p->data = ptr;
			p->capacity += 2;
			printf("提示:通訊錄增容成功\n");

		}
	}
}

void Addcontect(contect* p)
{
	int pos = -1;
	CheckCapacity(p);
		printf("請輸入姓名:>\n");
		scanf("%s",p->data[p->sz].name);
		printf("請輸入年齡:>\n");
		scanf("%d",&p->data[p->sz].age);
		printf("請輸入性別:>\n");
		scanf("%s",p->data[p->sz].sex);
		printf("請輸入電話:>\n");
		scanf("%s",p->data[p->sz].tele);
		printf("請輸入地址:>\n");
		scanf("%s",p->data[p->sz].address);
		p->sz++;
		system("cls");
		pos = search_name2(p->data[p->sz-1].name, p);
		if (pos == -1)
		{
			printf("添加成功\n");
		}
		else
		{
			printf("通訊錄中已經有此人\n");
			dele_name2(p->sz,p);
			p->sz--;
		}
}

void Showcontect(contect* p)
{
	if (p->sz == 0)
	{
		system("cls");
		printf("通訊錄為空\n");
	} 
	else
	{
		system("cls");
		printf("%-15s\t %-5s\t %-5s\t %-12s\t %-20s\t\n", "姓名","年齡","性別","電話","地址");
		for (int i = 0; i < p->sz; i++)
		{
			printf("%-15s\t %-5d\t %-5s\t %-12s\t %-20s\t\n",p->data[i].name,
			p->data[i].age,p->data[i].sex,p->data[i].tele,p->data[i].address);
		}

	}
}

int search_name2(char name[], contect* ps)
{
	for (int i = 0; i < ps->sz-1; i++)
	{
		if (strcmp(name, ps->data[i].name) == 0)
		{
			return i;
		}
	}
	return -1;
}

int search_name(char name[], contect* ps)
{
	for (int i = 0; i < ps->sz; i++)
	{
		if (strcmp(name, ps->data[i].name) == 0)
		{
			return i;
		}
	}
	return -1;
}

int search_tele(char tele[], contect* ps)
{
	for (int i = 0; i < ps->sz; i++)
	{
		if (strcmp(tele, ps->data[i].tele) == 0)
		{
			return i;
		}
	}
	return -1;
}

void dele_name2(int p,contect* ps)
{
	ps->data[p - 1] = ps->data[p];
}

void Deletecontect(contect* p)
{
	int input = 0;
	int input2 = 0;
	int pos = 0;
	char  name[10] = { 0 };
	char tele[20] = { 0 };
	system("cls");
	do
	{
		menu_deleat();
		scanf("%d",&input);
		switch (input)
		{
		case 1:
			printf("請輸入你要洗掉的人名字\n");
			scanf("%s",name);
			pos= search_name2(name,p);
			if (pos == -1)
			{
				printf("要洗掉的名字不存在\n");
				printf("\n");
			}
			else
			{
				printf("洗掉成功\n");
				int j = 0;
				for (j = pos; j < p->sz - 1; j++)
				{
					p->data[pos] = p->data[pos + 1];
				}
				p->sz--;
			}

			break;
		case 2:
			printf("請輸入你要洗掉的人的電話號碼\n");
			scanf("%s", tele);
			pos = search_tele(tele, p);
			if (pos == -1)
			{
				printf("要洗掉的電話號碼不存在\n");
				printf("\n");
			}
			else
			{
				printf("洗掉成功\n");
				int j = 0;
				for(j = pos; j < p->sz - 1; j++)
				{
					p->data[pos] = p->data[pos + 1];
				}
				p->sz--;
			}
			break;
		case 3:
			printf("你確定要全部洗掉通訊錄嗎? 1.確定 2.回到上一步\n");
			scanf("%d",&input2);
			if (input2 == 2);
			else
			{
				FILE* pf = fopen("contect.data", "wb");
				Deletinformation(p);
				system("cls");
				return;
			}
			break;
		case 0:
			system("cls");
			printf("回傳成功\n");
			return;
			break;
		default:
			printf("選擇錯誤,請重新選擇\n");
			break;
		}
	} while (input);

}

void Searchcontect(contect*ps)
{
	char name[20] = { 0 };
	char tele[20] = { 0 };
	int input = 0;
	int pos = 0;
	system("cls");
	do
	{
		menu_search();
		scanf("%d",&input);
		switch (input)
		{
		case 1:
			system("cls");
			printf("請輸入你要查找人的名字\n");
			scanf("%s",name);
			 pos = search_name(name, ps);
			if (pos == -1)
			{
				printf("你要找的名字不存在\n");
			}
			else
			{
				printf("%-15s\t%-4s\t%-5s\t%-12s\t%-20s\n", "姓名", "年齡", "性別", "電話", "住址");
				printf("%-15s\t%-4d\t%-5s\t%-12s\t%-20s\n",
					ps->data[pos].name,
					ps->data[pos].age,
					ps->data[pos].sex,
					ps->data[pos].tele,
					ps->data[pos].address);
			}
			printf("\n");
			printf("\n");
			break;
		case 2:
			system("cls");
			printf("請輸入你要查找人的電話號碼\n");
			scanf("%s",tele);
			 pos = search_tele(tele, ps);
			if (pos == -1)
			{
				printf("你要查找的電話號碼不存在\n");
			}
			else
			{
				printf("%-15s\t%-4s\t%-5s\t%-12s\t%-20s\n", "姓名", "年齡", "性別", "電話", "住址");
				printf("%-15s\t%-4d\t%-5s\t%-12s\t%-20s\n",
					ps->data[pos].name,
					ps->data[pos].age,
					ps->data[pos].sex,
					ps->data[pos].tele,
					ps->data[pos].address);
			}
			printf("\n");
			printf("\n");
			break;
		case 0:
			system("cls");
			printf("回傳成功\n");
			break;
		default:
			system("cls");
			printf("選擇錯誤,請重新選擇\n");
			break;
		}
	} while (input);
}

void Modifycontect(contect* ps)
{
	char name[MAX_NAME] = { 0 };
	char tele[MAX_TELE] = { 0 };
	int pos = 0;
	int input = 0;
	do
	{
		menu_modify();
		scanf("%d",&input);
		switch (input)
		{
		case 1:
			system("cls");
			printf("請輸入你要修改人的名字\n");
			scanf("%s", name);
			pos = search_name(name, ps);
			if (pos == -1)
			{
				printf("要修改的人不存在,請確定通訊錄資訊\n");
				int i = 0;
				printf("\n");
				printf("是否需要回傳選單確認資訊 1.回傳 2.重新尋找\n");
				scanf("%d",&i);
				if(i == 1)
				{
					return;
				}
			}
			else
			{
				int input2 = 0;
				do
				{
					menu_modify_option();
					scanf("%d",&input2);
					switch (input2)
					{
					case 1:
						printf("你要將原來的名字修改為\n");
						scanf("%s",ps->data[pos].name);
						system("cls");
						break;
					case 2:
						printf("你要將原來的年齡改為\n");
						scanf("%d",&ps->data[pos].age);
						system("cls");
						break;
					case 3:
						printf("你要將原來的性別改為\n");
						scanf("%s",ps->data[pos].sex);
						system("cls");
						break;
					case 4:
						printf("你要將原來的電話改為\n");
						scanf("%s",ps->data[pos].tele);
						system("cls");
						break;
					case 5:
						printf("你要將原來的地址改為\n");
						scanf("%s",ps->data[pos].address);
						system("cls");
						break;
					case 0:
						system("cls");
						printf("回傳成功\n");
						break;
					default:
						system("cls");
						printf("輸入錯誤,請重新輸入\n");
						break;
					}
				} while (input2);
			}
			break;
		case 2:
			system("cls");
			printf("請輸入你要修改人的電話號碼\n");
			scanf("%s", tele);
			pos = search_tele(tele, ps);
			if (pos == -1)
			{
				printf("要修改的人不存在,請確定通訊錄資訊\n");
				int i = 0;
				printf("\n");
				printf("是否需要回傳選單確認資訊 1.回傳 2.重新尋找\n");
				scanf("%d", &i);
				if (i == 1)
				{
					return;
				}
			}
			else
			{
				int input2 = 0;
				do
				{
					menu_modify_option();
					scanf("%d", &input2);
					switch (input2)
					{
					case 1:
						printf("你要將原來的名字修改為\n");
						scanf("%s", ps->data[pos].name);
						system("cls");
						break;
					case 2:
						printf("你要將原來的年齡改為\n");
						scanf("%d", &ps->data[pos].age);
						system("cls");
						break;
					case 3:
						printf("你要將原來的性別改為\n");
						scanf("%s", ps->data[pos].sex);
						system("cls");
						break;
					case 4:
						printf("你要將原來的電話改為\n");
						scanf("%s", ps->data[pos].tele);
						system("cls");
						break;
					case 5:
						printf("你要將原來的地址改為\n");
						scanf("%s", ps->data[pos].address);
						system("cls");
						break;
					case 0:
						system("cls");
						printf("回傳成功\n");
						break;
					default:
						system("cls");
						printf("輸入錯誤,請重新輸入\n");
						break;
					}
				} while (input2);
			}
			break;
		case 0:
			system("cls");
			printf("回傳成功\n");
			break;
		default:
			system("cls");
			printf("選擇錯誤,請重新選擇\n");
			break;
		}

	} while (input);
}

int CmpByName(const void* e1, const void* e2)
{
	return strcmp((const char*)e1, (const char*)e2);
}

void Sortcontect(contect* ps)
{
	qsort(ps->data,ps->sz,sizeof(people), CmpByName);
	system("cls");
	printf("排序成功\n");
}

void Deletinformation(contect* p)
{
	free(p->data);
	p->data= NULL;
	p->sz = 0;
}

void Savecontect(contect*ps)
{
	FILE* pf = fopen("contect.data", "wb");
	if (pf == NULL)
	{
		printf("記憶體不足,保存失敗\n");
		return;
	}
	for (int i = 0; i < ps->sz; i++)
	{
		fwrite(&(ps->data[i]),sizeof(people),1,pf);
	}
	fclose(pf);
	pf = NULL;
	printf("保存成功\n");
}

void LodeContact(contect* p)
{
	FILE* pf = fopen("contect.data", "rb");
	if (pf == NULL)
	{
		printf("加載通訊錄失敗\n");
		return;
	}
	people tmp = {0};
	while (fread(&tmp, sizeof(people), 1, pf))
	{
		CheckCapacity(p);
		p->data[p->sz] = tmp;
		p->sz++;
	}
	fclose(pf);
	pf = NULL;
}

7.小結

學校的c語言,圖書管理系統,學生成績系統,等等八九不離十,

我寫這篇文章的目的是梳理我寫這些題的程序與思路,所以代碼可能有些冗余,

轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/271611.html

標籤:其他

上一篇:Python 編程1000例(15):查找演算法——折半查找演算法

下一篇:教你速成指標進階

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 面試突擊第一季,第二季,第三季

    第一季必考 https://www.bilibili.com/video/BV1FE411y79Y?from=search&seid=15921726601957489746 第二季分布式 https://www.bilibili.com/video/BV13f4y127ee/?spm_id_fro ......

    uj5u.com 2020-09-10 05:35:24 more
  • 第三單元作業總結

    1.前言 這應該是本學期最后一次寫作業總結了吧。總體來說,對作業的節奏也差不多掌握了,作業做起來的效率也更高了。雖然和之前的作業一樣,作業中都要用到新的知識,但是相比之前,更加懂得了如何利用工具以及資料。雖然之間卡過殼,但總體而言,這幾次作業還算完成的比較好。 2.作業程序總結 相比前兩個單元,此單 ......

    uj5u.com 2020-09-10 05:35:41 more
  • 北航OO(2020)第四單元博客作業暨課程總結博客

    北航OO(2020)第四單元博客作業暨課程總結博客 本單元作業的架構設計 在本單元中,由于UML圖具有比較清晰的樹形結構,因此我對其中需要進行查詢操作的元素進行了包裝,在樹的父節點中存盤所有孩子的參考。考慮到性能問題,我采用了快取機制,一次查詢后盡可能快取已經遍歷過的資訊,以減少遍歷次數。 本單元我 ......

    uj5u.com 2020-09-10 05:35:48 more
  • BUAA_OO_第四單元

    一、UML決議器設計 ? 先看下題目:第四單元實作一個基于JDK 8帶有效性檢查的UML(Unified Modeling Language)類圖,順序圖,狀態圖分析器 MyUmlInteraction,實際上我們要建立一個有向圖模型,UML中的物件(元素)可能與同級元素連接,也可與低級元素相連形成 ......

    uj5u.com 2020-09-10 05:35:54 more
  • 6.1邏輯運算子

    邏輯運算子 1. && 短路與 運算式1 && 運算式2 01.運算式1為true并且運算式2也為true 整體回傳為true 02.運算式1為false,將不會執行運算式2 整體回傳為false 03.只要有一個運算式為false 整體回傳為false 2. || 短路或 運算式1 || 運算式2 ......

    uj5u.com 2020-09-10 05:35:56 more
  • BUAAOO 第四單元 & 課程總結

    1. 第四單元:StarUml檔案決議 本單元采用了圖模型決議UML。 UML檔案可以抽象為圖、子圖、邊的邏輯結構。 在實作中,圖的節點包括類、介面、屬性,子圖包括狀態圖、順序圖等。 采用了三次遍歷UML元素的方法建圖,第一遍遍歷建點,第二、三次遍歷設定屬性、連邊,實作圖物件的初始化。這里借鑒了一些 ......

    uj5u.com 2020-09-10 05:36:06 more
  • 談談我對C# 多型的理解

    面向物件三要素:封裝、繼承、多型。 封裝和繼承,這兩個比較好理解,但要理解多型的話,可就稍微有點難度了。今天,我們就來講講多型的理解。 我們應該經常會看到面試題目:請談談對多型的理解。 其實呢,多型非常簡單,就一句話:呼叫同一種方法產生了不同的結果。 具體實作方式有三種。 一、多載 多載很簡單。 p ......

    uj5u.com 2020-09-10 05:36:09 more
  • Python 資料驅動工具:DDT

    背景 python 的unittest 沒有自帶資料驅動功能。 所以如果使用unittest,同時又想使用資料驅動,那么就可以使用DDT來完成。 DDT是 “Data-Driven Tests”的縮寫。 資料:http://ddt.readthedocs.io/en/latest/ 使用方法 dd. ......

    uj5u.com 2020-09-10 05:36:13 more
  • Python里面的xlrd模塊詳解

    那我就一下面積個問題對xlrd模塊進行學習一下: 1.什么是xlrd模塊? 2.為什么使用xlrd模塊? 3.怎樣使用xlrd模塊? 1.什么是xlrd模塊? ?python操作excel主要用到xlrd和xlwt這兩個庫,即xlrd是讀excel,xlwt是寫excel的庫。 今天就先來說一下xl ......

    uj5u.com 2020-09-10 05:36:28 more
  • 當我們創建HashMap時,底層到底做了什么?

    jdk1.7中的底層實作程序(底層基于陣列+鏈表) 在我們new HashMap()時,底層創建了默認長度為16的一維陣列Entry[ ] table。當我們呼叫map.put(key1,value1)方法向HashMap里添加資料的時候: 首先,呼叫key1所在類的hashCode()計算key1 ......

    uj5u.com 2020-09-10 05:36:38 more
最新发布
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:20:47 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:20:25 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:20:17 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:20:10 more
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:19:44 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:19:07 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:18:57 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:18:49 more
  • 05單件模式

    #經典的單件模式 public class Singleton { private static Singleton uniqueInstance; //一個靜態變數持有Singleton類的唯一實體。 // 其他有用的實體變數寫在這里 //構造器宣告為私有,只有Singleton可以實體化這個類! ......

    uj5u.com 2023-04-19 08:42:51 more
  • 【架構與設計】常見微服務分層架構的區別和落地實踐

    軟體工程的方方面面都遵循一個最基本的道理:沒有銀彈,架構分層模型更是如此,每一種都有各自優缺點,所以請根據不同的業務場景,并遵循簡單、可演進這兩個重要的架構原則選擇合適的架構分層模型即可。 ......

    uj5u.com 2023-04-19 08:42:41 more