通訊錄管理系統

Lix_Lee發表於2020-12-27

通訊錄管理系統

你好,這是在學習了一段時間的C語言之後,在結合所學知識和網站學習的基礎下,編譯的第一個程式,可以作為參考,但不建議直接拿去用。萌新謹慎索取。在瀏覽過程中,如果發現哪方面不足,歡迎下方留言。

通訊錄管理系統詳解

該系統是基於連結串列和結構體建立,有連結串列基本的增刪查改,排序,查詢,插入,檔案的建立,儲存,讀取和一些小功能。在更改和查詢功能中,又分別將其細化,避免了很多不必要的麻煩。
本系統存在的問題也有很多,比如:插入採用的是尾插法,沒有運用其他的插入方法,比較單調,單一。排序功能還存在一些問題。 大家都是新手,不建議直接copy哦!!如果出了問題,哥哥概不負責。嘻嘻!!

一、 具體程式碼詳解如下

1.標頭檔案和結構體及變數定義

程式碼展示如下:

#include<stdio.h>
#include<string.h>
#include<stdlib.h>

struct Person
	{
	int num;
	char name[50];
	char  city[50];
	char  tel[13];
	char youbian[6];
	};
struct node
	{
	Person data;
	struct node *pnext;
	};
	struct node*phead =NULL;
	int count =0;

在結構體中定義數值域與指標域,數值域儲存聯絡人資訊,指標域儲存要連線的結構體地址,

2.使用的函式宣告

具體如下:

void createFace();//建立主選單
void createHeadNode();//建立標頭檔案
void addNewNode(struct node *phead);//新增聯絡人
void showAllNode(struct node *phead);//展示所有聯絡人
void deleteNodeByNum(struct node *phead);//刪除聯絡人
void findNodeByNum(struct node *phead);//通過編號查詢聯絡人
void xiugaiNodeByNum(struct node *phead);//修改聯絡人
void initData(struct node *phead);//讀取檔案
void flush_data(struct node *phead);//寫入檔案,並退出系統
void findNodeByDim(struct node *phead);//查詢相同城市聯絡人
int isSameNode(char input[], char name[]);//相同篩選
void Sort(struct node *phead);//排序
void find(struct node *phead);//查詢聯絡人
void face();//選單
void face2();//選單2

根據所需的功能運用不同的函式,千萬要記住函式的宣告!!!!千萬要記住!!!千萬要記住!!!重要的事情說三遍!!!!

2. 選單和主函式

程式碼如下

void createFace()
	{
	int b=0;
	initData(phead);
	printf("當前檔案中有%d條資料\n",count);
	printf("當前日期是:\t"); 
	system("date/t");
	system("time/t");
	printf("\t\t\t=====================歡迎使用通訊錄管理系統==================\n");
	printf("\t\t\t*                                                           *\n");
	printf("\t\t\t*                                                           *\n");
	printf("\t\t\t-------------------------------------------------------------\n");
	printf("\t\t\t**************************1.新增聯絡人***********************\n");
	printf("\t\t\t*                                                           *\n");
	printf("\t\t\t**************************2.刪除聯絡人***********************\n");
	printf("\t\t\t*                                                           *\n");
	printf("\t\t\t**************************3.查詢聯絡人***********************\n");
	printf("\t\t\t*                                                           *\n");
	printf("\t\t\t**************************4.修改聯絡人資訊*******************\n");
	printf("\t\t\t*                                                           *\n");
	printf("\t\t\t**************************5.檢視所有聯絡人*******************\n");
	printf("\t\t\t*                                                           *\n");
	printf("\t\t\t**************************6.排序*****************************\n");
	printf("\t\t\t*                                                           *\n");
	printf("\t\t\t**************************0.資料存檔並退出系統***************\n");
	printf("\t\t\t-------------------------------------------------------------\n");
	printf("\t\t\t*                                                           *\n");
	printf("\t\t\t*                                                           *\n");
	printf("\t\t\t=============================================================\n");
	while(1)
	{
	loop:printf("輸入選項前的數字:");
	int a,b;
		a=scanf("%d",&b);
		if (a!=1)
		{
			printf("幹哈呢!讓你輸個數字,你至於嗎?老實點!!!!"); 
			fflush(stdin);
			goto loop;
			
		}
		
			switch(b)
				{
				case 1:addNewNode(phead);break;
				case 2:deleteNodeByNum(phead);break;
				case 3:find(phead);break;
				case 4:xiugaiNodeByNum(phead);break;
				case 5:showAllNode(phead);break;
				case 6:Sort(phead);break;
				case 0:flush_data(phead);
				default: printf("輸入操作錯誤!沒有該選項!請重新輸入!");
	     		}
  }
}
int main()
{
     createHeadNode();
	 createFace();
	return 0;
}

該項功能中,增加了一個小程式,可以顯示當前時間。另外選單格式可以根據自己的喜好進行自行更改。為了此處避免一些小的bug,要防止滾鍵盤(使用goto語句)。只能輸入指令前的數字,輸入其他數字或字母無效。

時間顯示程式碼如下

printf("當前日期是:\t"); 
	system("date/t");
	system("time/t");

防止滾鍵盤程式碼如下:

loop:printf("輸入選項前的數字:");
	int a,b;
		a=scanf("%d",&b);
		if (a!=1)
		{
			printf("幹哈呢!讓你輸個數字,你至於嗎?老實點!!!!"); 
			fflush(stdin);
			goto loop;
			
		}

執行視窗如下:
在這裡插入圖片描述
只能輸入0~1數字,輸入其他無效。

3.新增聯絡人

void addNewNode(struct node *phead)	
	{
	system("cls");	
	face();
	struct node *pfind=phead;
	struct node *pnew=NULL;
	while (pfind->pnext!=NULL)
	{
		pfind=pfind->pnext;
	}
	pnew = (struct node*)malloc(sizeof(struct node));
	int x;
	loop:printf("請輸入編號:\n");
	x=scanf("%d",&pnew->data.num);
	if(pnew->data.num<=0)
	{
	printf("編號只能為數字!請重新輸入:\n");
	goto loop;
	}
	if (x!=1)
		{
			printf("幹哈呢!讓你輸個編號,你至於嗎?老實點!!!!"); 
			fflush(stdin);
			goto loop;
			
		}
	printf("請輸入姓名:\n");
	scanf("%s",pnew->data.name);
	printf("請輸入城市:\n");
	scanf("%s",pnew->data.city);
	int x1;
	loop1:printf("請輸入電話號碼(只能為11位!):\n");
	x1=scanf("%s",&pnew->data.tel);
	if (x1!=1)
		{
			printf("請輸入正確的電話號碼(只能為11位)!"); 
			fflush(stdin);
			goto loop1;
			
		}
	
	/*int y=pnew->data.tel;
	if(y>100000000000)
	{
		printf("請輸入正確的電話號碼!");
		goto loop1; 
	}*/
	int x3; 
	printf("請輸入郵編(只能為6位數字):\n");
	scanf("%s",pnew->data.youbian); 
	
	pnew->pnext=NULL;
	
	pfind->pnext=pnew;
	
	printf("%S的資訊錄入成功!\n",pnew->data.name);
	system("pause");
	system("cls");
	face();
}

該函式中還存在一些bug,未能將電話號碼和郵編規範到相應的數位,但在聯絡人編號、電話號碼、郵編處利用 goto語句限制了騎只能輸入編號。
另,該處新增聯絡人每次只能新增一個。每次新增一個成功後,會返回主選單。

4.刪除聯絡人

刪除一個聯絡人資訊,讓它的前一個指標直接連線到它的下一個指標,該指標脫離連結串列,再釋放掉。
注意:防止野指標出現!!!
在這裡插入圖片描述

程式碼如下:

void deleteNodeByNum(struct node *phead)
{
	system("cls");
	face();
	int num = 0;
	struct node *ptemp=NULL;
	struct node *pfind1=phead;
	struct node *pfind2=phead->pnext;
	start:printf("請輸入需要刪除的聯絡人的編號\n");
	scanf("%d",&num);
	
	
	while(pfind2!=NULL)
	{
		if(pfind2->data.num==num)
		{
		break;
		}
		
		pfind1=pfind1->pnext;
		pfind2=pfind2->pnext;
		
	}
	if(pfind2==NULL)
	{
		printf("輸入的編號有誤,未找到該聯絡人!\n");
		goto start;
	}
	else{
		ptemp=pfind2->pnext;
		free(pfind2);
		pfind2=NULL;
		pfind1->pnext=ptemp;
		printf("您已成功刪除該聯絡人!\n");
	}
	system("pause");
	system("cls");
	face();
}

該刪除功能是利用編號進行刪除聯絡人。
為方便快捷的進行功能的使用,在沒想結束後,我們會用清屏程式碼進行清屏。
同時要注意將選單顯示出來。
清屏程式碼如下:

system("pause");
	system("cls");
	face();

5.查詢聯絡人

查詢某一聯絡人資訊:首先需要遍歷連結串列找到聯絡人資訊,定義臨時指標儲存該聯絡人資訊再輸出。
本功能採用了編號查詢和相同城市查詢功能。
具體程式碼如下:
1.選單2

void find(struct node *phead)
{
	system("cls");
	face2();
	int b=0;
	while(1)
	{
	start:loop:printf("輸入選項前的數字:");
	int a,b,c;
		a=scanf("%d",&b);
		if (a!=1)
		{
			printf("幹哈呢!讓你輸個數字,你至於嗎?老實點!!!!"); 
			fflush(stdin);
			goto loop;
			
		}
		system("cls");
		face2();
			switch(b)
				{
				case 1:findNodeByNum(phead);break;
				case 2:findNodeByDim(phead);break;
				default: printf("輸入操作錯誤!沒有該選項!請重新輸入!");
	     		}
	     			printf("    是否要繼續查詢? 1:是  2:否\n");
					printf("       請輸入你的選擇:");
					scanf("%d",&c);
				switch(c) //goto語句實現是否迴圈
				{
					case 1:goto start;
					case 2:break;
					system("pause");
					system("cls");
					
					
				}
				face();
				return;
  }
}
			
		 

	

void face2()
{
	printf("\t\t\t\t\t\t---------------------------------\n");
	printf("\t\t\t\t\t\t*********************************\n");
	printf("\t\t\t\t\t\t**********1.按編號查詢***********\n");
	printf("\t\t\t\t\t\t                                 \n");
	printf("\t\t\t\t\t\t**********2.按城市名查詢*********\n");
	printf("\t\t\t\t\t\t                                 \n");
	printf("\t\t\t\t\t\t*********************************\n");
	printf("\t\t\t\t\t\t---------------------------------\n");
}

2.按編號查詢

void findNodeByNum(struct node *phead)
{
	int num=0;
	struct node *pfind=phead->pnext;
	printf("請輸入想要查詢的聯絡人的編號"); 
	scanf("%d",&num);
	while (pfind!=NULL)
	{
		if (pfind->data.num==num)
		{
			break;
			
		}
		pfind=pfind->pnext;
   	}
   if (pfind=NULL)
   {
   	printf("對不起,未找到該聯絡人!\n");

   }
   else
   {
   	printf("****************************************************************************************\n");
	printf("編號:%d\t姓名%s\t城市%s\t電話%s\t郵編%s\n",pfind->data.num,pfind->data.name,
	pfind->data.city,pfind->data.tel,pfind->data.youbian);
	printf("****************************************************************************************\n");

   }
   system("pause");
	system("cls");
	face2();

}

3.按城市名查詢

void findNodeByDim(struct node *phead){
	char input[20];
	struct node *pfind = phead->pnext;
	printf("請輸入城市名:\n");
	scanf("%s", input);
	while (pfind!=NULL){
		if (isSameNode(input,pfind->data.city)){
		printf("************************************************************************\n");
		printf("編號:%d\t姓名%s\t城市%s\t電話%s\t郵編%s\n",pfind->data.num,
		pfind->data.name,pfind->data.city,pfind->data.tel,pfind->data.youbian);
		printf("************************************************************************\n");
		}
		pfind=pfind->pnext;
		system("pause");
		system("cls");
		face();
	}
}
int isSameNode(char input[],char city[]){
	char *p1, *p2;
	p1 = input;
	p2 = city;
	while (*p1!='\0'){
		p2 = city;
		while (*p2!='\0'){
			if (*p1 == *p2){
				return 1;
			}
			p2++;
		}
		p1++;
	}
	return 0;
}

執行介面如下:
在這裡插入圖片描述
按照所需要的查詢方式輸入相應的編號。

6.檢視所有聯絡人

檢視所有聯絡人資訊:其實這就是一個遍歷連結串列並列印的過程,定義一個臨時指標儲存資訊一一將資訊輸出出來。
具體程式碼如下:

void showAllNode(struct node *phead)
{
	struct node *pfind=phead->pnext;
	while(pfind!=NULL)
	{
		printf("************************************************************************\n");
		printf("編號:%d\t姓名%s\t城市%s\t電話%s\t郵編%s\n",pfind->data.num,
		pfind->data.name,pfind->data.city,pfind->data.tel,pfind->data.youbian);
		printf("************************************************************************\n");
		pfind = pfind->pnext;
	}
	
	if(pfind=NULL)
	{
		printf("通訊錄空空如也!快點去新增你的通訊好友吧!");
	}
	 /*else
   {
   	printf("****************************************************************************************\n");
	printf("編號:%d\t姓名%s\t城市%s\t電話%s\t郵編%s\n",pfind->data.num,pfind->data.name,
	pfind->data.city,pfind->data.tel,pfind->data.youbian);
	printf("****************************************************************************************\n");
	pfind = pfind->pnext;
   }*/
  system("pause");
	system("cls");
	face();
}

7.修改聯絡人資訊

修改聯絡人資訊只需要編歷連結串列中找到聯絡人資訊,直接修改就行。
修改時要和新增相似有對各個資訊的限制建議將那些小個程式直接寫成函式。方便又快捷。
具體程式碼如下:

void xiugaiNodeByNum(struct node *phead) //第五部分:修改結點內容
{
		int b,a,c;
	struct node *pfind=phead;
	if(pfind==NULL)// 標頭檔案為空時,輸出通訊錄為空
	{
	
	printf("**********************************通訊錄為空!!!*********************************\n\n\n");
	}
	else
	{
		printf("    輸入要修改的聯絡人編號:	");
		loop:scanf("%d",&a);
		if(a<=0)
						{
							printf("編號不能小於等於0,請重新輸入:\n");
							goto loop;
						}
		for(pfind=phead->pnext;pfind!=NULL;pfind=pfind->pnext)
		{	
			start:printf("*********************************************************************************\n");
			printf("編號:%d\t姓名%s\t城市%s\t電話%s\t郵編%s\n",pfind->data.num,pfind->data.name,
			pfind->data.city,pfind->data.tel,pfind->data.youbian);
			printf("*********************************************************************************\n");
			printf("       	輸入想要修改什麼?\n");
				printf("\t\t\t\t1:修改編號\n");
				printf("\t\t\t\t2:修改姓名\n");
				printf("\t\t\t\t3:修改城市\n");
				printf("\t\t\t\t4:修改電話\n");
				printf("\t\t\t\t5:修改郵編\n");
				printf("\t\t\t\t請輸入你的選擇:");
				scanf("%d",&b);
				switch(b)
				{
					case 1:
						loop1:printf("\t請輸入新的編號:");
						scanf("%d",&pfind->data.num);
						if(pfind->data.num<=0)
						{
							printf("編號不能小於等於0,請重新輸入:\n");
							goto loop1;
						}
						break;
					case 2:
						printf("\t請輸入新的姓名:");
						scanf("%s",pfind->data.name);break;
					case 3:
						printf("\t請輸入新的城市:");
						scanf("%s",pfind->data.city);break;
					case 4:
						printf("\t請輸入新的電話:");
						scanf("%s",pfind->data.tel);break;
					case 5:
						printf("\t請輸入新的郵編:");
						scanf("%s",pfind->data.youbian);break; 
					
					default: printf("輸入操作錯誤,請重新輸入:"); 
				}
				system("cls");
				printf("修改成功!!!\n");
				printf("*********************************************************************************\n");
				printf("編號:%d\t姓名%s\t城市%s\t電話%s\t郵編%s\n",pfind->data.num,pfind->data.name,
				pfind->data.city,pfind->data.tel,pfind->data.youbian);
				printf("*********************************************************************************\n");
					system("pause");
					system("cls");
					
				printf("    是否要修改其他項? 1:是  2:否\n");
				printf("       請輸入你的選擇:");
					scanf("%d",&c);
				switch(c) //goto語句實現是否迴圈
				{
					case 1:goto start;
					case 2:break;
					system("pause");
					system("cls");
					
				}
				face();
		}
	}
	return;   //返回標頭檔案
}

要注意,在修改時將所需修改的聯絡人資訊調出,看著改更安心!!!
執行視窗展示:
在這裡插入圖片描述

8.讀取檔案及其輸入、輸出和儲存功能

該功能我也只略懂皮毛,具體學習還請進行自行搜尋。我就不多說了,上程式碼吧!


void initData(struct node *phead){
	struct node *pfind = phead;
	struct node *pnew = NULL;
	FILE *fp = NULL;
	fp = fopen("data.txt", "r");
	if (fp == NULL){
		printf("檔案讀取失敗\n");
		return;
	}
	while (1){
		pnew = (struct node*) malloc(sizeof(struct node));
		fscanf(fp,"%d%s%s%s%s",&pnew->data.num,pnew->data.name,
		pnew->data.city,pnew->data.tel,pnew->data.youbian);
		pnew->pnext = NULL;
		if (feof(fp)){
			break;
		}
		count++;
		pfind->pnext = pnew;
		pfind = pfind->pnext;
	}
	fclose(fp);
}
void flush_data(struct node *phead)
{
	struct node *pfind=phead->pnext;
	FILE *fp=NULL;
	fp=fopen("data.txt","w");
	
	while(pfind!=NULL)
	{
	fprintf(fp,"%d\t%s\t%s\t%s\t%s\n",pfind->data.num,pfind->data.name,
		pfind->data.city,pfind->data.tel,pfind->data.youbian);	
		pfind=pfind->pnext;
	}
	fclose(fp);
	printf("系統已退出\n");
	exit(0); 
}

9.排序功能

改功能在編寫時出現過問題,有時可以用,但有時就廢了。copy時請慎重。
程式碼如下:

void Sort(struct node *phead)  //排序 
{
	struct node *p,*q;
	int a;
	char b[20],c[20],d[20],e[20];
	for(p=phead->pnext;q!=NULL;p=p->pnext)
	{
		for(q=phead->pnext;q!=NULL;q=q->pnext)
		{
			if((p->data.num)>(q->data.num))
			{
				a=q->data.num;
				q->data.num=p->data.num;
				p->data.num=a;
				
				strcpy(b,q->data.name);
				strcpy(q->data.name,p->data.name);
				strcpy(p->data.name,b);
				
				strcpy(c,q->data.city);
				strcpy(q->data.city,p->data.city);
				strcpy(p->data.city,c);
				
				strcpy(d,q->data.tel);
				strcpy(q->data.tel,p->data.tel);
				strcpy(p->data.tel,d);
				
				strcpy(e,q->data.youbian);
				strcpy(q->data.youbian,p->data.youbian);
				strcpy(p->data.youbian,e);
				
				system("pause");
				system("cls");
				face();
			}
		}
	}
		
}

總結

本系統以連結串列知識為主,把連結串列的增刪查改理解之後,會發現其他功能與之其實都差不多。
如何編歷連結串列很重要,新手把這些理解之後基本大作業就能夠敲出來。
該系統還存在一些問題歡迎大家留言更正。
第一次寫部落格,還有點小激動, 希望這篇文章能幫助需要的人。
拜拜啦!!!!!

相關文章