完整版通訊錄(實現簡單具體易上手!!)

zhaocx111222333發表於2020-11-22

今天我們完成通訊錄的程式設計實現.
其中包含了:
新增聯絡人資訊
刪除指定聯絡人資訊
查詢指定聯絡人資訊
修改指定聯絡人資訊
顯示所有聯絡人資訊
清空所有聯絡人
以名字排序所有聯絡人

這幾項基本功能的函式實現.
這篇部落格是按照程式導向的具體的思路來完成的,所以新手很容易上手.

定義聯絡人和通訊錄結構體

1.定義通訊錄必定要定義一個以人為本的結構體用來儲存電話號和姓名.

2.聯絡人結構體完成,就需要一個通訊錄結構體來記錄多個數量的聯絡人,為了方便我們定義一個size(用來儲存已經存在的人數. [0, size) 就是有效區間)

3.建立出的陣列裡有 1024 個空間. 但是初始情況下, 通訊錄應該是空著的. 每次新增聯絡人, 裡面才會多出一個元素

typedef struct person{
	char name  [1024];
	char phnumber[1024];
}person;

typedef struct addressbook{
	person persons[MAX_PERSON];
	int size;
}addressbook;

選單函式

當我們完成了結構體的建立,按照思路,我們首先需要一個使用者互動介面,來展示給使用者.並在互動介面完成具體步驟的定義.

int menu(){
	printf("***************************\n");
	printf("*** 1. 新增聯絡人        **\n");
	printf("*** 2. 刪除聯絡人        **\n");
	printf("*** 3. 查詢聯絡人        **\n");
	printf("*** 4. 修改聯絡人        **\n");
	printf("*** 5. 顯示所有聯絡人    **\n");
	printf("*** 6. 清空所有聯絡人    **\n");
	printf("*** 7. 名字排序所有聯絡人**\n");
	printf("*** 0. 退出              **\n");
	printf("***************************\n");
	printf("輸入您的選擇:\n");
	int choice = 0;
	scanf("%d", &choice);
	return choice;
}

主體函式

1.新增聯絡人

定義一個函式,指向通訊錄所在的結構體.
其中注意點是,千萬要進行是否滿了的判斷,否則程式會發生不可預計的情況

void addperson(addressbook* addressbook) { 
	int Size = addressbook->size;//傳來了size的數字大小
	person* p = &addressbook->persons[Size];//指標傳來了
	if (Size >= MAX_PERSON) {
		printf("通訊錄已經滿了, 新增失敗!\n");
		return 0;
	}
	printf("輸入新增聯絡人\n"); 
	printf("請輸入新聯絡人的姓名: ");
	scanf("%s", p->name);
	printf("請輸入新聯絡人的電話: ");
	scanf("%s", p->phnumber);
	printf("新增聯絡人成功!\n");
	addressbook->size++;
}

這個函式實現了讓使用者輸入新的聯絡人的電話和姓名.
建立好一個專門的變數把要修改的 person 結構體變數給儲存好.

此處不能直接使用結構體變數 person .p 這種形式, 必須使用結構體指標.
因為:我們是希望修改全域性變數中的person 結構體.
而使用結構體變數的話, 相當於建立了一個區域性變數的結構體.
此時的修改只是針對該區域性變數生效, 隨著函式結束, 區域性變數就被釋放了.

2.刪除聯絡人

為了方便管理,我們利用陣列下標來進行人數的操作;
刪除聯絡人分為兩點:
第一種:

若需要刪除的聯絡人在最後一位,可以直接在總人數上-1進行刪除(size–)

第二種:

如果 id 對應的元素是中間元素, 把最後一個元素給放在需要刪除元素這裡
再刪除最後一個元素.

void delperson(addressbook* addressbook) {
	printf("刪除聯絡人\n");
	printf("請輸入要刪除的聯絡人的編號: ");
	int id = 0;
	scanf("%d", &id);
	if (id < 0 || id >= addressbook->size) {
		printf("您輸入的編號有誤!\n");
		return 0;
	}
	if (id == addressbook->size - 1) {
		addressbook->size--;
		printf("刪除成功!\n");
		return 0;
	}
	// 如果 id 對應的元素是中間元素, 把最後一個元素給bia過來
	addressbook->persons[id]
		= addressbook->persons[addressbook->size - 1];
	addressbook->size--;
	printf("刪除成功!\n");
}

3.查詢聯絡人

根據姓名查詢:

void findPerson(addressbook* addressbook) {
	printf("請輸入要查詢的姓名: ");
	char name[1024] = { 0 };
	scanf("%s", &name);
	for (int i = 0; i < addressbook->size; i++) {
		person* p = &addressbook->persons[i];
		if (strcmp(name, p->name) == 0) {//字串比較函式 ==0取1
			printf("[%d]\t\t%s\t\t%s\n", i, p->name, p->phnumber);
		}
		printf("不存在這個聯絡人!\n");
	}
	printf("查詢聯絡人完成!\n");
}

4.修改聯絡人

先要判斷這個人編號是否存在,然後依次修改姓名,電話號

void updateperson(addressbook* addressbook) {
	printf("請輸入你要修改人的編號");
	int num = 0;
	scanf("%d", &num);
	if (num > addressbook->size){
		printf("聯絡人不存在!");
	}
	person*p = &addressbook->persons[num];
	printf("輸入要改成的姓名:\n");
	char name[1024] = { 0 };
	scanf("%s", &name);
	strcpy(p->name, name);
	printf("輸入要改成的電話號:\n");
	char number[1024] = { 0 };
	scanf("%s", &number);
	strcpy(p->phnumber, number);
	printf("修改完成!\n");
}

5.顯示所有聯絡人

迴圈列印persons的全部內容

void printPerson(addressbook* addressbook) {
	printf("列印所有聯絡人\n");
	for (int i = 0; i < addressbook->size; i++) {
		person* p = &addressbook->persons[i];
		printf("[%d]\t\t%s\t\t%s\n", i, p->name, p->phnumber);
	}
	printf("共計 [%d] 條記錄\n", addressbook->size);
}

6.清空所有聯絡人

依據刪除最後一位的思路,迴圈刪除

void clearperson(addressbook* addressbook) {
	int num = addressbook->size;
	for (int i = 0; i < num; i++){
		addressbook->size--;
	}
	printf("清空聯絡人完成!\n");
}

7.聯絡人排序

這個排序採用了簡單地氣泡排序完成,方便理解(按照字典序)

char sortperson(addressbook* addressbook){
	int i = 0;
	int j = 0;
	for (i = 0; i < addressbook->size - 1; i++)
	{
		for (j = 0; j<addressbook->size - 1 - i; j++)
		{
			if (strcmp(addressbook->persons[j].name, (addressbook->persons[j + 1]).name)>0)
			{
				person tmp = addressbook->persons[j];
				addressbook->persons[j] = addressbook->persons[j + 1];
				addressbook->persons[j + 1] = tmp;
			}
		}
	}
}

8.初始化函式

針對整個通訊錄進行初始化.
只要把 size 設成 0 即可.

void init(addressbook* addressbook){
	addressbook->size = 0;
}

typedef void(*Func)(addressbook*);
addressbook addressBook;

主函式

在主函式中插入了一個轉移表

相比於用if-else語句更加方便,如果你沒有學過轉移表,可以自己寫成if-else格式.

int main(){
	Func funcs[] = {
		NULL,
		addperson,
		delperson,
		findPerson,
		updateperson,
		printPerson,
		clearperson,
		sortperson
	};
	while (1){
	int	 choice = menu();
	if (choice == 0){
		printf("再見!\n");
		break;
	}
	funcs[choice](&addressBook);
	}
	system("pause");
	return 0;
}

標頭檔案及巨集定義

#include<stdio.h>
#include<stdlib.h>
#include <string.h>
#define MAX_PERSON 1024

原始碼

#include<stdio.h>
#include<stdlib.h>
#include <string.h>
#define MAX_PERSON 1024
typedef struct person{
	char name  [1024];
	char phnumber[1024];
}person;

typedef struct addressbook{
	person persons[MAX_PERSON];
	int size;
}addressbook;

int menu(){
	printf("***************************\n");
	printf("*** 1. 新增聯絡人        **\n");
	printf("*** 2. 刪除聯絡人        **\n");
	printf("*** 3. 查詢聯絡人        **\n");
	printf("*** 4. 修改聯絡人        **\n");
	printf("*** 5. 顯示所有聯絡人    **\n");
	printf("*** 6. 清空所有聯絡人    **\n");
	printf("*** 7. 名字排序所有聯絡人**\n");
	printf("*** 0. 退出              **\n");
	printf("***************************\n");
	printf("輸入您的選擇:\n");
	int choice = 0;
	scanf("%d", &choice);
	return choice;
}


void addperson(addressbook* addressbook) { 
	int Size = addressbook->size;//傳來了size的數字大小
	person* p = &addressbook->persons[Size];//指標傳來了
	if (Size >= MAX_PERSON) {
		printf("通訊錄已經滿了, 新增失敗!\n");
		return 0;
	}
	printf("輸入新增聯絡人\n"); 
	printf("請輸入新聯絡人的姓名: ");
	scanf("%s", p->name);
	printf("請輸入新聯絡人的電話: ");
	scanf("%s", p->phnumber);
	printf("新增聯絡人成功!\n");
	addressbook->size++;
}

void delperson(addressbook* addressbook) {
	printf("刪除聯絡人\n");
	printf("請輸入要刪除的聯絡人的編號: ");
	int id = 0;
	scanf("%d", &id);
	if (id < 0 || id >= addressbook->size) {
		printf("您輸入的編號有誤!\n");
		return 0;
	}
	if (id == addressbook->size - 1) {
		addressbook->size--;
		printf("刪除成功!\n");
		return 0;
	}
	// 如果 id 對應的元素是中間元素, 把最後一個元素給bia過來
	addressbook->persons[id]
		= addressbook->persons[addressbook->size - 1];
	addressbook->size--;
	printf("刪除成功!\n");
}

void findPerson(addressbook* addressbook) {
	printf("請輸入要查詢的姓名: ");
	char name[1024] = { 0 };
	scanf("%s", &name);
	for (int i = 0; i < addressbook->size; i++) {
		person* p = &addressbook->persons[i];
		if (strcmp(name, p->name) == 0) {//字串比較函式 ==0取1
			printf("[%d]\t\t%s\t\t%s\n", i, p->name, p->phnumber);
		}
		printf("不存在這個聯絡人!\n");
	}
	printf("查詢聯絡人完成!\n");
}

void printPerson(addressbook* addressbook) {
	printf("列印所有聯絡人\n");
	for (int i = 0; i < addressbook->size; i++) {
		person* p = &addressbook->persons[i];
		printf("[%d]\t\t%s\t\t%s\n", i, p->name, p->phnumber);
	}
	printf("共計 [%d] 條記錄\n", addressbook->size);
}

void updateperson(addressbook* addressbook) {
	printf("請輸入你要修改人的編號");
	int num = 0;
	scanf("%d", &num);
	if (num > addressbook->size){
		printf("聯絡人不存在!");
	}
	person*p = &addressbook->persons[num];
	printf("輸入要改成的姓名:\n");
	char name[1024] = { 0 };
	scanf("%s", &name);
	strcpy(p->name, name);
	printf("輸入要改成的電話號:\n");
	char number[1024] = { 0 };
	scanf("%s", &number);
	strcpy(p->phnumber, number);
	printf("修改完成!\n");
}

void clearperson(addressbook* addressbook) {
	int num = addressbook->size;
	for (int i = 0; i < num; i++){
		addressbook->size--;
	}
	printf("清空聯絡人完成!\n");
}

char sortperson(addressbook* addressbook){
	int i = 0;
	int j = 0;
	for (i = 0; i < addressbook->size - 1; i++)
	{
		for (j = 0; j<addressbook->size - 1 - i; j++)
		{
			if (strcmp(addressbook->persons[j].name, (addressbook->persons[j + 1]).name)>0)
			{
				person tmp = addressbook->persons[j];
				addressbook->persons[j] = addressbook->persons[j + 1];
				addressbook->persons[j + 1] = tmp;
			}
		}
	}
}

void init(addressbook* addressbook){
	addressbook->size = 0;
}

typedef void(*Func)(addressbook*);
addressbook addressBook;
int main(){
	Func funcs[] = {
		NULL,
		addperson,
		delperson,
		findPerson,
		updateperson,
		printPerson,
		clearperson,
		sortperson
	};
	while (1){
	int	 choice = menu();
	if (choice == 0){
		printf("再見!\n");
		break;
	}
	funcs[choice](&addressBook);
	}
	system("pause");
	return 0;
}

相關文章