(动态增加内存初始大小为2每次扩容大小为2(修改宏可更改)+文件存储联系人
数据每次使用时读取文件内容保存在内存中)
编译器 vs2013
通讯录可以用来存储联系人个人的信息,每个人的信息包括:姓 名、性
别、年龄、电话、住址
提供方法:
1.添加联系人信息
2.删除指定联系人信息
3.查找指定联系人信息
4.修改指定联系人信息
5.显示所有联系人信息
6.清空所有联系人
7.以名字排序所有联系人
mian.c
#include"test.h"
void menu(){
printf("╔═══════════════════════════════════════════════════╗\n");
printf("║═══════════════════ 通讯录 ══════════════════════║\n");
printf("║═══ ═══║\n");
printf("║═══ 1.新建联系人 2.删除联系人 ═══║\n");
printf("║═══ 3.查找联系人 4.修改联系人 ═══║\n");
printf("║═══ 5.清空联系人 6.排序联系人 ═══║\n");
printf("║═══ 7.打印联系人 0.退出 ═══║\n");
printf("║═══ ═══║\n");
printf("╚═══════════════════════════════════════════════════╝\n");
}
int main(){
int flag = 1;
int select = 0;
contact_t *ct=NULL;
InitContact(&ct);
while (flag){
menu();
int cout = 0;
printf("请选择:[0-7]#:\n");
scanf("%d", &select);
switch (select){
case 1:
AddContact(&ct);
break;
case 2:
DelectContact(ct);
break;
case 3:
SearchContact(ct);
break;
case 4:
ModifyContact(ct);
break;
case 5:
ClearContact(ct);
break;
case 6:
SortContact(ct);
break;
case 7:
PrintContact(ct);
break;
case 0:
printf("欢迎下次使用!!!\n");
SaveContact(ct);
Sleep(2000);
flag = 0;
break;
default:
printf("输入有误请重新输入!!!!!\n");
break;
}
}
system("pause");
return 0;
}
test.h(头文件)
#ifndef _TEST_H_
#define _TEST_H_
#include<stdio.h>
#include<windows.h>
#include<assert.h>
#pragma warning(disable:4996)
//person内部元素的大小
#define NAME_SIZE 32
#define SEX_SIZE 8
#define TELPHONE_SIZE 16
#define ADDRESS_SIZE 128
#define INIT_NUM 2//通讯录的初始容量
#define INC_NUM 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 contacts[0];//柔性数组
}contact_t;
void AddContact(contact_t **ct);
void InitContact(contact_t **ct);
void SearchContact(contact_t *ct);
void ClearContact(contact_t *ct);
void DelectContact(contact_t *ct);
void ModifyContact(contact_t *ct);
void PrintContact(contact_t *ct);
void SortContact(contact_t *ct);
void SaveContact(contact_t *ct);
#endif
test.c(函数的实现)
#include"test.h"
void InitContact(contact_t **ct)
{
/*assert(ct);
*ct = (contact_t *)malloc(sizeof(person_t)*INIT_NUM + sizeof(contact_t));
if (ct == NULL){
perror("malloc");
exit(1);
}
memset(*ct, 0, sizeof(person_t)*INIT_NUM + sizeof(contact_t));//对申请的内存进行初始化
(*ct)->cap = INIT_NUM;*/
FILE *fp = fopen(SAVE_FILE, "rb");
if (fp == NULL){
*ct = (contact_t *)malloc(sizeof(contact_t)+INIT_NUM*sizeof(person_t));
if (*ct == NULL){
perror("malloc");
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");
exit(2);
}
memcpy(*ct, &temp, sizeof(contact_t));
fread((*ct)->contacts, sizeof(person_t), (*ct)->size, fp);
printf("Using Sava.txt Init!\n");
fclose(fp);
}
}
static int IsFull(contact_t *ct){
assert(ct);
return ct->size == ct->cap;
}
static int Inc(contact_t **ct){
assert(ct);
contact_t *temp = (contact_t*)realloc(*ct,sizeof(contact_t)+((*ct)->cap + INC_NUM)*sizeof(person_t));
if (temp == NULL){
perror("relloc");
return 0;
}
*ct = temp;
(*ct)->cap += INC_NUM;
printf("自动扩容成功!!");
return 1;
}
static IsExist(contact_t *ct, person_t *p){//判断联系人是否存在
assert(ct);
assert(p);
int i = 0;
for (; i < ct->size; i++){
if (strcmp(ct->contacts[i].name, p->name)==0){
return 1;
}
}
return 0;
}
void AddContact(contact_t **ct){//添加联系人
assert(ct);
if (!IsFull(*ct) || Inc(ct)){
person_t p;
printf("请输入新增联系人的姓名:\n");
scanf("%s", p.name);
printf("请输入新增联系人的性别:\n");
scanf("%s", p.sex);
printf("请输入新增联系人的年龄:\n");
scanf("%d", &(p.age));
printf("请输入新增联系人的电话:\n");
scanf("%s", p.telphone);
printf("请输入新增联系人的住址:\n");
scanf("%s", p.address);
if (IsExist(*ct, &p)){
printf("该联系人已经存在!!");
return;
}
else{
memcpy((*ct)->contacts + (*ct)->size, &p, sizeof(p));//拷贝
(*ct)->size += 1;
}
}
else{
printf("扩容失败!!");
}
}
static SearchCore(contact_t *ct, char *str){//返回联系人的下标
int i = 0;
for (; i < ct->size; i++){
person_t *p = ct->contacts + i;
if (strcmp(str, p->name) == 0){
return i;
}
}
return -1;
}
void SearchContact(contact_t *ct){//查找联系人
assert(ct);
printf("请输入你要查找的联系人的姓名:\n");
char name[NAME_SIZE];
scanf("%s", name);
int i = SearchCore(ct, name);
if (i+1){
printf("╔═════════════════════════════════════════════════════════════╗\n");
printf("%3s\t%6s\t%2s%8s%16s%20s\n", "║序号", "姓名", "年龄", "性别", "电话", "地址║");
printf("%3d\t%6s\t%2d%8s%18s%17s\n",
i + 1,
ct->contacts[i].name,
ct->contacts[i].age,
ct->contacts[i].sex,
ct->contacts[i].telphone,
ct->contacts[i].address);
printf("╚═════════════════════════════════════════════════════════════╝\n");
}
else{
printf("你要查找的人 %s 不存在!\n", name);
}
}
void ClearContact(contact_t *ct){
assert(ct);
Sleep(2000);
ct->size = 0;
printf("通讯录已经清空\n");
}
void DelectContact(contact_t *ct){//删除联系人
assert(ct);
char name[NAME_SIZE];
printf("请输入你要删除的联系人姓名:\n");
scanf("%s", name);
int ret = SearchCore(ct, name);
if (ret){
ct->contacts[ret] = ct->contacts[(ct->size) - 1];
(ct->size) -= 1;
}
else{
printf("通讯录中没有联系人%s", name);
}
}
void ModifyContact(contact_t *ct){//修改联系人
assert(ct);
char name[NAME_SIZE];
printf("请输入你要修改的联系人姓名:\n");
scanf("%s", name);
int ret = SearchCore(ct, name);
if (ret){
printf("请输入修改后的姓名:\n");
scanf("%s", ct->contacts[ret].name);
printf("请输入修改后的年龄:\n");
scanf("%d", ct->contacts[ret].age);
printf("请输入修改后的性别:\n");
scanf("%s", ct->contacts[ret].sex);
printf("请输入修改后的电话:\n");
scanf("%s", ct->contacts[ret].telphone);
printf("请输入修改后的地址:\n");
scanf("%s", ct->contacts[ret].address);
printf("原联系人%s修改成功\n", name);
}
else{
printf("通讯录中没有联系人%s", name);
}
}
static int IsEmpty(contact_t *ct){//判断联系人是否为空
return (ct->size)==0;
}
void PrintContact(contact_t *ct){//打印联系人
assert(ct);
printf("╔═════════════════════════════════════════════════════════════╗\n");
printf("%3s\t%6s\t%2s%8s%16s%20s\n", "║序号", "姓名", "年龄", "性别", "电话", "地址║");
for (int i = 0; i < ct->size; i++){
printf("%3d\t%6s\t%2d%8s%18s%17s\n",
i + 1,
ct->contacts[i].name,
ct->contacts[i].age,
ct->contacts[i].sex,
ct->contacts[i].telphone,
ct->contacts[i].address);
}
printf("╚═════════════════════════════════════════════════════════════╝\n");
}
static int Compare(const void *p1, const void *p2){//使用qsort时提供的回调函数
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->contacts, ct->size, sizeof(person_t), Compare);
}
}
void SaveContact(contact_t *ct){//退出时将数据保存到文件中
assert(ct);
FILE *fp = fopen(SAVE_FILE, "wb");
if (fp == NULL){
perror("svae error!\n");
return;
}
fwrite(ct, sizeof(contact_t), 1, fp);
fwrite(ct->contacts, sizeof(person_t), ct->size, fp);
}
运行界面: