1. 程式人生 > >將結構體實現的簡易通訊錄改成動態的版本

將結構體實現的簡易通訊錄改成動態的版本

之前實現的一次結構體型通訊錄電話本容量固定為1000,如果只需存50人,就浪費950的容量,如果存

2000人,容量就不夠了,所以這次動態開闢一個電話本容量。並且將之前的版本測試部分用函式指標陣列簡化完善一下。

之前版本(點選這裡

程式碼如下:

1.標頭檔案部分:

#ifndef __CONTACTS_H__
#define __CONTACTS_H__
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <error.h>
#define MAX_NAME 10
#define MAX_SEX 5
#define MAX_TELE 12
#define MAX_ADDR 25



typedef struct M	//定義一個結構體用於儲存聯絡人資訊
{
	char name[MAX_NAME];
	char sex[MAX_SEX];
	char tele[MAX_TELE];
	char address[MAX_ADDR];
	int age;
}M;
typedef struct C	//定義一個結構體儲存
{
	M *contacts;
	int count;
	int v;	//定義一個電話本容量,如果人數超過電話本容量,則動態開闢額外的容量。
}C;

void menu();	//選單
void Add(C* p);	//新增聯絡人
void Delete(C* p);	//刪除聯絡人
void Research(C* p);	//查詢聯絡人
void Change(C* p);	//修改聯絡人
void Display(C* p);	//顯示所有聯絡人
void Format(C* p);	//清除聯絡人
void Rank(C* p);	//給聯絡人排序
void Exit(C* p);	//用於退出並釋放開闢的動態記憶體

#endif

2.函式實現部分

#include "contacts.h"

void menu()	//列印選單
{
	printf("***********************************\n");
	printf("*1.新增指定聯絡人 2.刪除指定聯絡人*\n");
	printf("*3.查詢指定聯絡人 4.修改指定聯絡人*\n");
	printf("*5.顯示所有聯絡人 6.清空所有聯絡人*\n");
	printf("*7.排序所有聯絡人 0.退出(exit)  *\n");
	printf("***********************************\n");

}
int Isexist(C* p,char* name)
{
	int ret = 0;
	int i = 0;
	for(i=0; i<p->count; i++)
	{
		if(strcmp(p->contacts[i].name,name)==0)
		{
			return i;
		}
	}
	return -1;
}
void Add(C* p)	//新增聯絡人
{
	if(p->count == p->v)
	{
		M* temp = (M*)realloc(p->contacts,sizeof(M)*(p->v+5)); //如果電話本人數將和容量相等了,則額外開闢5個聯絡人的容量
		if(temp == NULL)
			printf("%s",strerror(errno));
		else
			p->contacts = temp;
		p->v += 3;
	
	}
	printf("請輸入姓名:>");
	scanf("%s",p->contacts[p->count].name);
	printf("請輸入性別:>");
	scanf("%s",p->contacts[p->count].sex);
	printf("請輸入電話:>");
	scanf("%s",p->contacts[p->count].tele);
	printf("請輸入地址:>");
	scanf("%s",p->contacts[p->count].address);
	printf("請輸入年齡:>");
	scanf("%d",&p->contacts[p->count].age);
	p->count++;	//新增完成後count指向後一個元素,方便下一次操作
	printf("新增完成\n");
}

void Delete(C* p)	//刪除聯絡人
{
	int ret = 0;
	int i = 0;
	char name[20];
	printf("請輸入要刪除聯絡人姓名:>");
	scanf("%s",name);
	ret = Isexist(p,name);
	if(ret != -1)
	{
		for(i=ret; i<p->count; i++)
		{
			p->contacts[i] = p->contacts[i+1];	//從該聯絡人後依次覆蓋
		}
		printf("刪除完成!\n");
	}
	else
		printf("此人不存在\n");
}

void Research(C* p)	//輸出查詢人資訊
{
	int ret = 0;
	char name[20];
	printf("請輸入要查詢聯絡人姓名:>");
	scanf("%s",name);
	ret = Isexist(p,name);
	if(ret != -1)
	{
		printf("此人姓名為:>%s\n",p->contacts[ret].name);
		printf("此人性別為:>%s\n",p->contacts[ret].sex);
		printf("此人年齡為:>%d\n",p->contacts[ret].age);
		printf("此人電話為:>%s\n",p->contacts[ret].tele);
		printf("此人住址為:>%s\n",p->contacts[ret].address);
	}
	else
		printf("查無此人\n");
}
void Change(C* p)	//修改聯絡人資訊
{
	int ret = 0;
	char name[20];
	printf("請輸入要修改聯絡人姓名:>");
	scanf("%s",name);
	ret = Isexist(p,name);
	if(ret != -1)
	{
		printf("修改姓名為:>");
		scanf("%s",p->contacts[ret].name);
		printf("修改性別為:>");
		scanf("%s",p->contacts[ret].sex);
		printf("修改年齡為:>");
		scanf("%d",&p->contacts[ret].age);
		printf("修改電話為:>");
		scanf("%s",p->contacts[ret].tele);
		printf("修改地址為:>");
		scanf("%s",p->contacts[ret].address);
	}
	else
		printf("查無此人\n");
}

void Display(C* p)	//顯示所有人資訊
{
	int i = 0;
	printf("所有人資訊為:>\n");
	for(i=0; i<p->count; i++)	//從第一個聯絡人依次輸出資訊
	{
		printf("%s\t",p->contacts[i].name);
		printf("%s\t",p->contacts[i].sex);
		printf("%d\t",p->contacts[i].age);
		printf("%s\t",p->contacts[i].tele);
		printf("%s\t",p->contacts[i].address);
		printf("\n");
	}
}

void Format(C* p)	//清除所有聯絡人
{
	int n = 0;
	printf("確認清除所有聯絡人?1.確認 2.按錯了:>");
	scanf("%d",&n);
	if(n == 1)
	{
		p->count = 0;	//將count清空完成清除
		printf("清除完成\n");
	}
	else
		printf("正在返回......\n");
	
}
void Rank(C* p)	//將所有聯絡人按照姓名排序
{
	int i = 0;
	int k = 0;
	for(i=0; i<p->count-1; i++)	//一手冒泡解決
	{
		for(k=0; k<p->count-i-1; k++)
		{
			if(strcmp(p->contacts[k].name,p->contacts[k+1].name)>0)
			{
				M temp;
				temp = p->contacts[k];
				p->contacts[k] = p->contacts[k+1];
				p->contacts[k+1] = temp;
			}
		}
	}
	printf("排序完成\n");
}
void Exit(C* p)
{
	free(p->contacts);
	p->contacts = NULL; //防止成為野指標
	printf("正在退出...\n");
}



3.測試部分
#include "contacts.h"


C con;
void test()
{
	void (*ppp[8])(C* p) = {Exit,Add,Delete,Research,Change,Display,Format,Rank};//定義一個函式指標陣列存放函式地址
	int input;
	menu();
	do{
		printf("請選擇:>");
		scanf("%d",&input);
		if(0<=input<8)
			ppp[input](&con);
		else
			printf("輸入錯誤!");
	
	}
	while(input);
}


int main()
{
	test();
	return 0;
}