C語言實現通訊錄系統——容量自增,文件版本


     頭文件maillist.h


#ifndef _MAILLIST_H_
#define _MAILLIST_H_

#include<stdio.h>
#include<windows.h>
#include<assert.h>
#define INIT_MAIL_SIZE 64          //定義宏表示通訊錄容量
#define INC_SIZE 64             //宏表示自增容量
#define FILE_NAME "maillistFile.txt"    
#pragma warning (disable:4996)
typedef struct person   //結構體變量,指針,二級指針。表示人的姓名等信息
{
	char name[32];
	char sex[4];
	char age[4];
	char tel[16];
	char address[64];
}person_t, *person_p, **person_pp;
typedef struct mail    //結構體變量,指針,二級指針。表示通訊錄相關信息
{
	int size;
	int cap;
	person_p maillist;
}mail_t, *mail_p, **mail_pp;
//相關函數的聲明
void menu();
void initMail(mail_pp m);
void addMail(mail_p m, person_p p);
void deleteMail(mail_p m);
void findMail(mail_p m);
void changeMail(mail_p m);
void desplayMail(mail_p m);
void clearMail(mail_p m);
void nameSort(mail_p m);
void desdoryMail(mail_p m);

int fileStore(mail_p m);
int fileLoad(mail_p m);

#endif 

     函數實現maillist.c

#include "maillist.h"    //引入頭文件
//內部static函數,判斷通訊錄,滿返回1,否則返回0
static int isMailFull(mail_p m)
{
	assert(m); //斷言
	return m->size >= m->cap ? 1 : 0;
}
//判斷通訊錄,爲空時返回1,否則返回0
static int isMailEmpty(mail_p m)
{
	assert(m);
	if (m->size == 0)
	{
		printf("Your maillist is empty!\n");
		return 1;
	}
	return 0;
}
//通訊錄容量自增函數
static int incMail(mail_p m)
{
	assert(m);
	person_p p = realloc(m->maillist, (m->cap + INC_SIZE)*sizeof(person_t));
	if (NULL == p)
	{
		perror("realloc");
		return 0;
	}
	m->maillist = p;
	m->cap += INC_SIZE;
	printf("inc success!\n");
	return 1;
}
//字符串比較
static int strCmp(const void* x, const void* y)
{
	return strcmp((*(person_p)x).name, (*(person_p)y).name);
}
//交換結構體變量
static void swap(person_p x, person_p y)
{
	person_t tmp = *x;
	*x = *y;
	*y = tmp;
}
//界面
void menu()
{
	printf("*************************************************************\n");
	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");
}
//初始化通訊錄,並用malloc函數爲之分配空間
void initMail(mail_pp m)
{
	assert(m);
	*m = (mail_p)malloc(sizeof(mail_t));
	if (NULL == *m)
	{//判斷內存分配是否成功
		perror("malloc");
		exit(1);
	}
	(*m)->maillist = (person_p)malloc(sizeof(person_t)*INIT_MAIL_SIZE);
	if (NULL == (*m)->maillist)
	{
		perror("malloc");
		exit(2);
	}
	(*m)->cap = INIT_MAIL_SIZE;
	(*m)->size = 0;
	fileLoad(*m);
}

int fileLoad(mail_p m)
{
	assert(m);
	FILE* fp = fopen(FILE_NAME, "rb");
	if (NULL == fp)
	{
		perror("fopen");
		return -2;
	}
	person_t p;
	while (1)
	{
		fread(&p, sizeof(person_t), 1, fp);
		if (feof(fp))
		{
			break;
		}
		addMail(m, &p);
	}
	fclose(fp);
	return 0;
}

int fileStore(mail_p m)
{
	assert(m);
	FILE* fp = fopen(FILE_NAME, "wb");
	if (NULL == fp)
	{
		perror("fopen");
		return -1;
	}
	int i = 0;
	for (i = 0; i < m->size; i++)
	{
		fwrite(m->maillist + i, sizeof(person_t), 1, fp);
	}
	fclose(fp);
	return 0;
}
//銷燬分配的內存空間
void desdoryMail(mail_p m)
{
	assert(m);
	fileStore(m);//文件存儲
	free(m->maillist);
	m->maillist = NULL;
	free(m);
	m = NULL;
}
//添加聯繫人
void addMail(mail_p m, person_p p)
{
	assert(m);
	if ((!isMailFull(m)) || incMail(m))
	{
		int pos = m->size;
		m->maillist[pos] = *p;
		m->size++;
	}
}
//刪除聯繫人
void deleteMail(mail_p m)
{
	assert(m);
	if (!isMailEmpty(m))
	{
		char name[32];
		printf("Please input the name maillist you delete : ");
		scanf("%s", name);
		int i = 0;
		for (i = 0; i < m->size; i++)
		{
			if (strcmp(m->maillist[i].name, name) == 0)
			{
				swap(m->maillist + i, m->maillist + m->size - 1);
				m->size--;
			}
		}
		if (i == m->size)
		{
			printf("no man!\n");
		}
	}
}
//查找
void findMail(mail_p m)
{
	assert(m);
	if (!isMailEmpty(m))
	{
		char name[32];
		printf("Please input the name of maillist you find : ");
		scanf("%s", name);
		int i = 0;
		for (i = 0; i < m->size; i++)
		{
			if (strcmp(m->maillist[i].name, name) == 0)
			{
				printf("name\tsex\tage\ttel\t\taddress\n");
				printf("%s\t%s\t%s\t%s\t%s\n", m->maillist[i].name, m->maillist[i].sex,
					m->maillist[i].age, m->maillist[i].tel, m->maillist[i].address);
				break;
			}
		}
		if (i == m->size)
		{
			printf("no man!\n");
		}
	}
}
//修改
void changeMail(mail_p m)
{
	assert(m);
	if (!isMailEmpty(m))
	{
		printf("Please input the name of list you want to change ->");
		char name[32];
		scanf("%s", name);
		int i;
		for (i = 0; i < m->size; i++)
		{
			if (strcmp(name, m->maillist[i].name) == 0)
			{
			again:	printf("Please input message you want to change(name|sex|age|tel|address)->");
				char input[16];
				char change[64];
				scanf("%s", input);
				if (strcmp(input, "name") == 0)
				{
					printf("Please input new name ->");
					scanf("%s", change);
					strcpy(m->maillist[i].name, change);
				}
				else if (strcmp(input, "sex") == 0)
				{
					printf("Please input sex ->");
					scanf("%s", change);
					strcpy(m->maillist[i].sex, change);
				}
				else if (strcmp(input, "age") == 0)
				{
					printf("Please input age ->");
					scanf("%s", change);
					strcpy(m->maillist[i].age, change);
				}
				else if (strcmp(input, "tel") == 0)
				{
					printf("Please input new tel ->");
					scanf("%s", change);
					strcpy(m->maillist[i].tel, change);
				}
				else if (strcmp(input, "address") == 0)
				{
					printf("Please input new address ->");
					scanf("%s", change);
					strcpy(m->maillist[i].address, change);
				}
				else
				{
					goto again;
				}
				printf("Congratulationgs,you successed changemessage!\n");
				printf("Are you want to changed again?(Y|N)\n");
				char s = 0;
				getchar();
				scanf("%c", &s);
				if ((s == 'y') || (s == 'Y'))
				{
					goto again;
				}
				else
				{
					break;
				}
			}
		}
		if (i == m->size)
		{
			printf("no man\n");
		}
	}
}
//顯示全部聯繫人
void desplayMail(mail_p m)
{
	assert(m);
	if (!isMailEmpty(m))
	{
		printf("name\tsex\tage\ttel\t\taddress\n");
		int i = 0;
		for (i = 0; i < m->size; i++)
		{
			printf("%s\t%s\t%s\t%s\t%s\n", m->maillist[i].name, m->maillist[i].sex,
				m->maillist[i].age, m->maillist[i].tel, m->maillist[i].address);
		}
	}
}
//清空聯繫人
void clearMail(mail_p m)
{
	assert(m);
	if (!isMailEmpty(m))
	{
		m->size = 0;
		printf("clear mailist success!\n");
	}
}
//以名字排序所有聯繫人
void nameSort(mail_p m)
{
	assert(m);
	if (!isMailEmpty(m))
	{
		qsort(m->maillist, m->size, sizeof(person_t), strCmp);
	}
	desplayMail(m);
}

     測試main.c

#include "maillist.h"
//添加聯繫人
static void myAddMail(mail_p m)
{
	assert(m);
	person_t p;
	printf("name\tsex\tage\ttel\t\taddress\n");
	scanf("%s %s %s %s %s", &p.name, &p.sex, &p.age, &p.tel, &p.address);
	addMail(m, &p);
	printf("Congratulations,you successed addMessage!\n");
}

int main()
{
	mail_p mymail = NULL;
	initMail(&mymail);
	int input = 0;
	int done = 0;
	menu();
	while (!done)
	{
		printf("Please choose <0—7> : ");
		scanf("%d", &input);
		switch (input)
		{//選擇對通訊錄進行的操作
		case 0:
			printf("bye~\n");
			done = 1;
			break;
		case 1:
			myAddMail(mymail);
			break;
		case 2:
			deleteMail(mymail);
			break;
		case 3:
			findMail(mymail);
			break;
		case 4:
			changeMail(mymail);
			break;
		case 5:
			desplayMail(mymail);
			break;
		case 6:
			clearMail(mymail);
			break;
		case 7:
			nameSort(mymail);
			break;
		default:
			printf("error input!\n");
			break;
		}
	}
	desdoryMail(mymail);
	system("pause");
	return 0;
}


        如有錯誤,歡迎指出!







發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章