C语言学习之通讯录实现

1.具体功能:增删改查、排序及清空整个通讯录

2.可实现通讯录的自动扩容

3.程序退出可保存通讯录

part A:contact.h

#ifndef _CONTACT_H_
#define _CONTACT_H_

#include 
#include 
#include 
#include 

#pragma warning(disable:4996)

#define NAME_SIZE 32
#define SEX_SIZE 8
#define TELPHONE_SIZE 16
#define ADDRESS_SIZE 128

//通讯录的初始信息

#define INIT_NUM 2
#define INC_SIZE 2

//文件信息
#define SAVE_FILE "save.txt"

typedef struct person{
	char name[NAME_SIZE];
	char sex[SEX_SIZE];
	int age;
	char telphone[TELPHONE_SIZE];
	char address[ADDRESS_SIZE];
}person_t;

typedef struct contact{
	int cap;
	int size;
	person_t friends[0];
}contact_t;

void InitContact(contact_t **ct);
void AddFriend(contact_t **ct);
void DelFriend(contact_t *ct);
void ModFriend(contact_t *ct);
void ShowContact(contact_t *ct);
void SearchFriend(contact_t *ct);
void ClearContact(contact_t *ct);
void SortContact(contact_t *ct);
void SaveContact(contact_t *ct);

#endif

part B:main.c

#include "contact.h"

void ShowMenu()
{
	printf("##################################\n");
	printf("# 1.Add      2.Del     3.Search  #\n");
	printf("# 4.Mod      5.Show    6.Clear   #\n");
	printf("# 7.Sort               0.Exit    #\n");
	printf("##################################\n");
}


int main()
{
	contact_t *ct = NULL;
	InitContact(&ct);
	int quit = 0;
	while (!quit){
		ShowMenu();
		int select = 0;
		scanf("%d", &select);

		switch (select){
		case 1:
			AddFriend(&ct);
			break;
		case 2:
			DelFriend(ct);
			break;
		case 3:
			SearchFriend(ct);
			break;
		case 4:
			ModFriend(ct);
			break;
		case 5:
			ShowContact(ct);
			break;
		case 6:
			ClearContact(ct);
			break;
		case 7:
			SortContact(ct);
			break;
		case 0:
			SaveContact(ct);
			quit = 1;
			break;
		default:
			printf("输入有误,请重新输入\n");
			break;
		}
	}

	system("pause");
	return 0;
}

part C:contact.c

#include "contact.h"

void InitContact(contact_t **ct)
{
	assert(ct);
	FILE *fp = fopen(SAVE_FILE, "rb");
	if (fp == NULL){
		*ct = (contact_t *)malloc(sizeof(contact_t)+INIT_NUM*sizeof(person_t));
		if (NULL == *ct){
			perror("malloc error");
			exit(1);
		}
		(*ct)->size = 0;
		(*ct)->cap = INIT_NUM;
		printf("Using Default Init!\n");
	}
	else{
		contact_t temp;
		fread(&temp, sizeof(contact_t), 1, fp);
		*ct = (contact_t *)malloc(sizeof(contact_t)+temp.cap * sizeof(person_t));
		if (ct == NULL){
			perror("malloc error");
			exit(2);
		}
		memcpy(*ct, &temp, sizeof(contact_t));
		fread((*ct)->friends, sizeof(person_t), (*ct)->size, fp);
		printf("Using Save.txt Init!\n");
		fclose(fp);
	}

}

static void ModMenu()
{
	printf("##################################\n");
	printf("# 1.Name      2.Sex       3.Age  #\n");
	printf("# 4.Telphone  5.Address   0.Eixt #\n");
	printf("##################################\n");
}

static int IsExit(contact_t *ct, person_t *p)
{
	assert(ct);
	assert(p);
	int i = 0;
	for (; i < ct->size; i++){
		if (strcmp(ct->friends[i].name, p->name) == 0){
			return 1;
		}
	}
	return 0;
}

static int IsFull(contact_t *ct)
{
	return ct->size == ct->cap;
}

static int IsEmpty(contact_t *ct)
{
	return ct->size == 0;
}

static int SearchCore(contact_t *ct, const char *name_p)
{
	assert(ct);
	assert(name_p);
	int i = 0;
	for (; i < ct->size; i++){
		person_t *p = ct->friends + i;
		if (strcmp(p->name, name_p) == 0){
			return i;
		}
	}
	return -1;
}

static int IncCap(contact_t **ct)
{
	assert(ct);
	contact_t *ct_temp = (contact_t *)realloc(*ct, sizeof(contact_t)+((*ct)->cap + INC_SIZE) * sizeof(person_t));
	if (ct_temp == NULL){
		perror("realloc error");
		return 0;
	}
	*ct = ct_temp;
	(*ct)->cap += INC_SIZE; 
	printf("扩容成功!\n");
	return 1;
}

void AddFriend(contact_t **ct)
{
	assert(ct);
	if (!IsFull(*ct) || IncCap(ct)){
		//1.通讯录没有满    2.扩容成功
		person_t p;
		printf("请输入新增用户姓名# ");
		scanf("%s", p.name);
		printf("请输入新增用户的性别# ");
		scanf("%s", p.sex);
		printf("请输入新增用户的年龄# ");
		scanf("%d", &p.age);
		printf("请输入新增用户的电话# ");
		scanf("%s", p.telphone);
		printf("请输入新增用户的地址# ");
		scanf("%s", p.address);

		//判断当前用户是否存在?
		if (IsExit(*ct, &p)){
			printf("%s 已经存在,请不要重复存储!\n", p.name);
			return;
		}
		memcpy((*ct)->friends + (*ct)->size, &p, sizeof(p));
		//拷贝结构体指针p指向的空间中的内容到结构体数组(通讯录)中
		//(*ct)->size代表从数组起始位置向后的偏移数,代表通讯录中的第size个用户
		(*ct)->size += 1;
		printf("新增用户 %s 成功!\n", p.name);
	}
	else{
		printf("扩容失败!\n");
	}
}

void ShowContact(contact_t *ct)
{
	assert(ct);
	int i = 0;
	printf("\n|cap: %6d | size: %6d |\n\n", ct->cap, ct->size);
	printf("|%-10s|%-10s|%-10s|%-10s|%-10s|\n", "姓名", "性别", "年龄", "电话", "住址");
	for (; i < ct->size; i++){
		person_t *p = ct->friends + i;
		printf("|%-10s|%-10s|%-10d|%-10s|%-10s|\n", p->name, p->sex, p->age, p->telphone, p->address);
	}
	printf("\n");
}

void DelFriend(contact_t *ct)
{
	assert(ct);
	printf("请输入你要 删除的用户的姓名# ");
	char name[NAME_SIZE];
	scanf("%s", name);
	int i = SearchCore(ct, name);
	if (i >= 0){
		ct->friends[i] = ct->friends[ct->size - 1];
		ct->size -= 1;
		printf("删除成功!\n");
	}
	else{
		printf("你要删除的用户 %s 不存在\n", name);
	}
}

void SearchFriend(contact_t *ct)
{
	assert(ct);
	printf("请输入你要查找的用户姓名# ");
	char name[NAME_SIZE];
	scanf("%s", name);
	int i = SearchCore(ct, name);
	if (i >= 0){
		person_t *p = ct->friends + i;
		printf("|%-10s|%-10s|%-10d|%-10s|%-10s|\n", p->name, p->sex, p->age, p->telphone, p->address);
	}
	else{
		printf("你要查找的用户 %s 不存在!", name);
	}
}

static int CmpPerson(const char *p1, const char *p2)
{
	assert(p1);
	assert(p2);
	person_t *_p1 = (person_t *)p1;
	person_t *_p2 = (person_t *)p2;

	return strcmp(_p1->name, _p2->name);
}

void SortContact(contact_t *ct)
{
	assert(ct);
	if (!IsEmpty(ct)){
		qsort(ct->friends, ct->size, sizeof(person_t), CmpPerson);
		//  起始地址,排序元素个数,每个元素的大小
	}
}

void ClearContact(contact_t *ct)
{
	assert(ct);
	ct->size = 0;
}

void ModFriend(contact_t *ct)
{
	assert(ct);
	printf("请输入你要修改的用户姓名# ");
	char name[NAME_SIZE];
	scanf("%s", name);
	int i = SearchCore(ct, name);
	if (i < 0){
		printf("该用户不存在,请重新输入!\n");
		return;
	}
	else{
		int quit = 0;
		while (!quit){
			ModMenu();
			int select = 0;
			printf("请输入要修改的选项# ");
			scanf("%d", &select);
			person_t *p = ct->friends + i;
			switch (select){
			case 1:
				printf("请输入修改后的姓名# ");
				scanf("%s", p->name);
				break;
			case 2:
				printf("请输入修改后的性别# ");
				scanf("%s", p->sex);
				break;
			case 3:
				printf("请输入修改后的年龄# ");
				scanf("%d", &p->age);
				break;
			case 4:
				printf("请输入修改后的电话# ");
				scanf("%s", p->telphone);
				break;
			case 5:
				printf("请输入修改后的住址# ");
				scanf("%s", p->address);
				break;
			case 0:
				quit = 1;
				break;
			default:
				printf("输入有误,请重新输入!\n");
				break;
			}
		}
	}
}

void SaveContact(contact_t *ct)
{
	assert(ct);
	FILE *fp = fopen(SAVE_FILE, "wb");
	if (fp == NULL){
		perror("save error!\n");
		return;
	}
	fwrite(ct, sizeof(contact_t), 1, fp);
	fwrite(ct->friends, sizeof(person_t), ct->size, fp);

	fclose(fp);
}

 

你可能感兴趣的:(C语言)