笔者个人认为这块挺难的,他对于指针的理解要求比较高。对于文件操作也要足够熟悉。
话不多说,上代码。
目录
一.MAIN函数的构造
这段笔者认为比较可取的地方在于enum和switch的搭配。
#include"contact.h"
void menu()
{
printf("********************************\n");
printf("******* 1.add 2.del *******\n");
printf("******* 3.show 4.save *******\n");
printf("******* 5.modify 6.search******\n");
printf("******* 7.sort 0.exit ******\n");
printf("********************************\n");
}
int main()
{
int input = 0;
struct Conn con;//con就是通讯录
InitContact(&con);
do
{
menu();
scanf("%d", &input);
switch (input)
{
case ADD:
AddContact(&con);
break;
case DEL:
DelContact(&con);
break;
case SHOW:
ShowContact(&con);
break;
case SAVE:
SaveContact(&con);
break;
case MODIFY:
ModifyContact(&con);
break;
case SEARCH:
SearchContact(&con);
break;
case SORT:
SortContact(&con);
break;
case EXIT:
DestoryContact(&con);
printf("退出通讯录\n");
break;
}
} while (input);
return 0;
}
二.函数构造
#include"contact.h"
void CheckContact(struct Conn* ps)
{
if (ps->size == ps->capacity)
{
struct Contact* ptr = (struct Contact*)realloc(ps->data, (ps->capacity + 5) * sizeof(Contact));
if (ptr != NULL)
{
ps->data = ptr;
ps->capacity += 5;
printf("增容成功\n");
}
else
{
printf("增容失败\n");
}
}
}
void LoadContact(Conn* ps)
{
//加载
struct Contact tmp = { 0 };
FILE* pfread = fopen("contact.txt", "rb");
if (pfread == NULL)
{
printf("LoadContact:%s\n", strerror(errno));
}
else
{
while (fread(&tmp, sizeof(Contact), 1, pfread))
{
CheckContact(ps);
ps->data[ps->size] = tmp;
ps->size++;
}
fclose(pfread);
pfread = NULL;
}
}
void InitContact(struct Conn* ps)
{
ps->data=(struct Contact*)malloc(INITAMOUNT * sizeof(struct Contact));
if (ps->data == NULL)
{
return;
}
ps->size = 0;
ps->capacity = INITAMOUNT;
LoadContact(ps);
}
void AddContact(struct Conn* ps)
{
//判断是否需要扩容。
CheckContact(ps);
printf("请输入名字:>");
scanf("%s", &ps->data[ps->size].name);
printf("请输入性别:>");
scanf("%s", &ps->data[ps->size].sex);
printf("请输入年龄:>");
scanf("%d", &ps->data[ps->size].age);
printf("请输入电话:>");
scanf("%s", &ps->data[ps->size].tele);
printf("请输入地址:>");
scanf("%s", &ps->data[ps->size].addr);
printf("添加成功\n");
ps->size++;
}
void ShowContact(struct Conn* ps)
{
if (ps->size == 0)
{
printf("通讯录为空\n");
}
else
{
int i = 0;
//先打印标题
printf("%-8s\t%-2s\t%-2s\t%-10s\t%-10s\n", "名字", "性别", "年龄", "电话", "地址");
for (i = 0; i < ps->size; i++)
{
printf("%-8s\t%-2s\t%-2d\t%-10s\t%-10s\n",
ps->data[i].name,
ps->data[i].sex,
ps->data[i].age,
ps->data[i].tele,
ps->data[i].addr);
}
}
}
static int Find_Byname(const struct Conn* ps, char name[MAX_NAME])
{
int i = 0;
for (i = 0; i < ps->size; i++)
{
if (0 == strcmp(ps->data[i].name, name))
{
return i;
}
}
return -1;
}
void DelContact(struct Conn* ps)
{
char name[MAX_NAME];
printf("请输入要删去人的姓名\n");
scanf("%s", &name);
int pos = Find_Byname(ps, name);
if (pos == -1)
{
printf("通讯录中没有此人的信息\n");
}
else
{
for (int i = pos; i < ps->size - 1; i++)
{
ps->data[i] = ps->data[i + 1];
}
ps->size--;
printf("删除成功\n");
}
}
void SearchContact(struct Conn* ps)
{
//在Conn中寻找,找到就打印
char name[MAX_NAME];
printf("请输入要寻找人的姓名\n");
scanf("%s", name);
int pos = Find_Byname(ps, name);
if (pos == -1)
{
printf("通讯录中无此人\n");
}
else
{
printf("%-8s\t%-2s\t%-2s\t%-10s\t%-10s\n", "名字", "性别", "年龄", "电话", "地址");
printf("%-8s\t%-2s\t%-2d\t%-10s\t%-10s\n",
ps->data[pos].name,
ps->data[pos].sex,
ps->data[pos].age,
ps->data[pos].tele,
ps->data[pos].addr);
}
}
void ModifyContact(struct Conn* ps)
{
char name[MAX_NAME];
printf("请输入要修改人的姓名\n");
scanf("%s", &name);
int pos = Find_Byname(ps, name);
if (pos == -1)
{
printf("通讯录中查无此人\n");
}
else
{
printf("可以修改\n");
printf("请输入名字:>");
scanf("%s", &ps->data[pos].name);
printf("请输入性别:>");
scanf("%s", &ps->data[pos].sex);
printf("请输入年龄:>");
scanf("%d", &ps->data[pos].age);
printf("请输入电话:>");
scanf("%s", &ps->data[pos].tele);
printf("请输入地址:>");
scanf("%s", &ps->data[pos].addr);
printf("修改成功\n");
}
}
void DestoryContact(struct Conn* ps)
{
free(ps->data);
ps->data = NULL;
}
void SaveContact(struct Conn* ps)
{
FILE* pfwrite = fopen("contact.txt", "wb");
if (pfwrite == NULL)
{
//报错位置
printf("SaveContact:%s\n", strerror(errno));
return;
}
else
{
//写通讯录中的数据到文件中去
int i = 0;
for (i = 0; i < ps->size; i++)
{
fwrite(&ps->data[i], sizeof(Contact), 1, pfwrite);
}
fclose(pfwrite);
pfwrite = NULL;
}
printf("保存成功\n");
}
void SortContact(struct Conn* ps)
{
//根据名字首字母大小排序
int i, j;
int flag = 1;
for (i = 0; i < ps->size; i++)
{
for (j = 0; j < ps->size - i - 1; j++)
{
if (strcmp(ps->data[j].name, ps->data[j + 1].name) >= 0)
{
flag = 0;
struct Contact tmp = ps->data[j];
ps->data[j] = ps->data[j + 1];
ps->data[j + 1] = tmp;
}
}
if (flag == 1)
{
break;
}
}
printf("排序成功\n");
ShowContact(ps);
}
三.头文件
#pragma once
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
//对姓名 年龄 性别 电话 住址定义宏
#define MAX_NAME 20
#define MAX_SEX 4
#define MAX_TELE 20
#define MAX_ADDR 20
#define INITAMOUNT 5 ///初始化通讯录只能放5个
enum OPTION
{
EXIT,
ADD,
DEL,
SHOW,
SAVE,
MODIFY,
SEARCH,
SORT
};
struct Contact
{
char name[MAX_NAME];
char sex[MAX_SEX];
char tele[MAX_TELE];
char addr[MAX_ADDR];
int age;
};
struct Conn
{
struct Contact* data;
//随时记录通讯录大小
int size;
//通讯录容量
int capacity;
};
void InitContact(struct Conn* ps);
void SaveContact(struct Conn* ps);
void DestoryContact(struct Conn* ps);
void ModifyContact(struct Conn* ps);
void DelContact(struct Conn* ps);
void ShowContact(struct Conn* ps);
void AddContact(struct Conn* ps);
void SearchContact(struct Conn* ps);
void SortContact(struct Conn* ps);
fwrite , fread 这几个函数真的难住了笔者。
四.结果预览