用文件的方法实现一个通讯录;
通讯录可以用来存储1000个人的信息,每个人的信息包括:
姓名、性别、年龄、电话、住址
提供方法:
1. 添加联系人信息
2. 删除指定联系人信息
3. 查找指定联系人信息
4. 修改指定联系人信息
5. 显示所有联系人信息
6. 清空所有联系人
7. 以名字排序所有联系人
实现之前,我们应该先准备一个头文件。这个程序呢,还是相当简单的,不用紧张,我们一步步的来实现它。
*建议读者复制下来,在程序内收缩函数体进行浏览会结构感会更清晰。
contact.h
#ifndef _CONTACT_H
#define _CONTACT_H
#include<stdio.h>
#include<windows.h>
#include<stdlib.h>
#include<string.h>
#define NAME_LENGTH 32//名字长度
#define SEX_LENGTH 3//性别数组长度
#define TEL_LENGTH 16//电话长度
#define ADDR_LENGTH 128//地址长度
#define INIT_NUM 3//初始化扩容大小
#define INC_NUM 2 //每次扩容大小
#define FILE_NAME "contact.data"//宏定义文件的名称,优点:可以方便整体修改
typedef struct contact
{
char name[NAME_LENGTH];
char sex[SEX_LENGTH];
char ages;
char tel[TEL_LENGTH];
char addr[ADDR_LENGTH];
};
typedef struct A
{
struct contact*arr;
int i;
int capacity;
};
enum op
{
EXIT,
ADD,
DEL,
SEARCH,
MODIFY,
DISPLAY,
CLEAR,
SORT
};
void print_menu(); //打印程序菜单
void check(struct A*con);//空间扩展检查
void add_contact(struct A*con);//添加联系人信息
void init_contact(struct A*con);//初始化联系人信息数组
int find_position(struct A*pcon); //查找指定联系人的位置
int delete_contact(struct A*pcon);//删除指定联系人
void modify_contact(struct A*pcon);//修改指定联系人信息
int find_contact(struct A* pcon);//查找并输入该联系人的信息
void display_contact(struct A*pcon);//打印所有联系人信息
void put_empty(struct A*pcon);//清空所有联系
void sort_contact(struct A*pcon);//按名字对联系人进行排序
void save(struct A*pcon);//将结构体的内容保存到文件中
void load(struct A*pcon);//把文件FILE_NAME的内容加载到结构体当中
#endif
接着,就应该准备我们的 整体框架 。此处,我们添加了一个通讯录登录密码功能。另外为什么要传结构体指针进行传参呢?
1.结构体传参不会降级,直接拷贝所有内容,这样呢就浪费了很多栈区的空间,并且效率会降低。所以传结构体指针。
test.c
#include"contact.h"
void test()
{
struct A con;
char checkSecret[200];
int input = 1;
int i = 0;
init_contact(&con);
printf("欢迎来到通讯录管理程序!\n");
printf("请输入管理员密码:");
for (i = 2; i >= 0; i--)
{
gets_s(checkSecret, 200);
if (strcmp(123456, checkSecret) == 0)
{
printf("恭喜您,登陆成功!\n");
break;
}
printf("温馨提示:您还有最后%d次机会.\n", i);
printf("请再次输入密码:");
}
if (i < 0)
{
exit(1);
}
while (input)
{
print_menu();
printf("请选择0-8:");
scanf_s("%d", &input);
switch (input)
{
case ADD:
add_contact(&con);
break;
case DEL:
delete_contact(&con);
break;
case SEARCH:
find_contact(&con);
break;
case MODIFY:
modify_contact(&con);
break;
case DISPLAY:
display_contact(&con);
break;
case CLEAR:
put_empty(&con);
break;
case SORT:
sort_contact(&con);
break;
case EXIT:
save(&con);
break;
default:
printf("请输入0-8!\n");
break;
}
}
}
int main()
{
test();
system("pasue");
return 0;
}
再接着,我们来实现结构框架下所对应的函数实现:
main.c
#include"contact.h"
void init_contact(struct A* pcon)
{
pcon->i = 0;
pcon->arr = (struct contact*)malloc(INIT_NUM *sizeof(struct contact));
memset(pcon->arr, 0, INIT_NUM*sizeof(struct contact));
if ((pcon->arr) == NULL)
{
printf("memory has been used up!\n");
exit(0);
}
pcon ->capacity = INIT_NUM;
load(pcon);
}
void check(struct A* con)
{
if (con->i == con->capacity)
{
int sz = con->capacity + INC_NUM;
con->arr = (struct contact*)realloc(con->arr,sz*(sizeof(struct contact)));
/* if (temp_pcon == NULL)
{
printf("memory has been used up!\n");
return -1;
}
*/
con->capacity += INC_NUM;
//return 0;
}
}
void add_contact(struct A*con)
{
printf("添加联系人信息\n");
check(con);
printf("请输入姓名:");
scanf_s("%s", con->arr[con->i].name, NAME_LENGTH);
printf("请输入性别:");
scanf_s("%s", con->arr[con->i].sex, SEX_LENGTH);
printf("请输入年龄:");
scanf_s("%d", &con->arr[con->i].ages);
printf("请输入电话:");
scanf_s("%s", con->arr[con->i].tel, TEL_LENGTH);
printf("请输入住址:");
scanf_s("%s", con->arr[con->i].addr, ADDR_LENGTH);
con->i++;
printf("添加成功!\n");
}
void print_menu()
{
printf("******************************************************\n");
printf("*** 1.添加联系人信息 2.删除指定联系人信息 ****\n");
printf("*** 3.查找指定联系人信息 4.修改指定联系人信息 ****\n");
printf("*** 5.显示所有联系人信息 6.清空所有联系人 ****\n");
printf("*** 7.以名字排序所有联系人 8.退出系统 ****\n");
printf("******************************************************\n");
}
int delete_contact(struct A*pcon)
{
int i = 0;
printf("删除联系人\n");
int ret = find_position(pcon);
if (ret != -1)
{
for (i = ret; i < (pcon->i)-1; i++)
{
pcon->arr[i] = pcon->arr[i++];
}
pcon->i--;
printf("删除成功!\n");
return 0;
}
else
{
printf("没有找到该联系人\n");
printf("删除失败!\n");
return 1;
}
}
//查找并输入该联系人的信息
int find_contact(struct A* pcon)
{
printf("查找联系人\n");
int ret = find_position(pcon);
if (ret != -1)
{
printf("姓名:%s\n", pcon->arr[ret].name);
printf("性别:%s\n", pcon->arr[ret].sex);
printf("年龄:%d\n", pcon->arr[ret].ages);
printf("电话号码:%s\n", pcon->arr[ret].tel);
printf("地址:%s\n", pcon->arr[ret].addr);
return 1;
}
printf("该联系人不存在!\n");
return 0;
}
//查找指定联系人的位置
int find_position(struct A*pcon)
{
int i = 0;
char name[NAME_LENGTH];
printf("请输入您所要查找的名字:");
scanf_s("%s",name,NAME_LENGTH);
for (i = 0; i < pcon->i; i++)
{
if (strcmp(pcon->arr[i].name, name) == 0)
{
return i;
}
}
return -1;
}
void modify_contact(struct A*pcon)
{
printf("修改联系人信息!\n");
int ret = find_position(pcon);
if (ret != -1)
{
printf("请输入姓名:");
scanf_s("%s", pcon->arr[pcon->i].name, NAME_LENGTH);
printf("请输入性别:");
scanf_s("%s", pcon->arr[pcon->i].sex, SEX_LENGTH);
printf("请输入年龄:");
scanf_s("%d", &pcon->arr[pcon->i].ages);
printf("请输入电话:");
scanf_s("%s", pcon->arr[pcon->i].tel, TEL_LENGTH);
printf("请输入住址:");
scanf_s("%s", pcon->arr[pcon->i].addr, ADDR_LENGTH);
printf("修改成功!\n");
}
else
{
printf("没有找到该联系人\n");
printf("修改失败!\n");
}
}
void display_contact(struct A*pcon)
{
printf("显示所有联系人信息:\n");
printf("%-32s%-8s%-5s%-16s%-128s\n", "姓名", "性别", "年龄", "电话", "地址");
int i = 0;
for (i= 0; i < pcon->i; i++)
{
printf("%-32s%-8s%-5d%-16s%-128s\n", pcon->arr[i].name,
pcon->arr[i].sex, pcon->arr[i].ages, pcon->arr[i].tel,
pcon->arr[i].addr);
}
}
void put_empty(struct A*pcon)
{
printf("清空联系人!\n");
memset(pcon->arr, 0, (pcon->capacity)*sizeof(struct contact));
init_contact(pcon);
}
void sort_contact(struct A*pcon)
{
printf("按姓名进行排序\n");
char ch = 0;
int i = 0, j = 0;
printf("请选择排序方式(‘<’代表由z->a排序,‘>’代表由a->z排序):\n");
fflush(stdin);
scanf_s("%c", &ch);
printf("\n");
int flag = 0;
if (ch == '<')
{
for (i = 0; i < pcon->i; i++)
{
flag = 0;
for (j = i + 1; j < pcon->i - i-1; j++)
{
if (strcmp(pcon->arr[i].name, pcon->arr[j].name) < 0)
{
struct contact tmp = { 0 };
tmp = pcon->arr[i];
pcon->arr[i] = pcon->arr[j];
pcon->arr[j] = tmp;
flag = 1;
}
}
if (flag == 0)
{
break;
}
}
}
else
{
for (i = 0; i < pcon->i - 1; i++)
{
flag = 0;
for (j = i + 1; j < pcon->i - i - 1; j++)
{
if (strcmp(pcon->arr[i].name, pcon->arr[j].name) > 0)
{
struct contact tmp = { 0 };
tmp = pcon->arr[i];
pcon->arr[i] = pcon->arr[j];
pcon->arr[j] = tmp;
flag = 1;
}
}
if (flag == 0)
{
break;
}
}
}
printf("排序成功!\n");
}
//将结构体的内容保存到文件中
void save(struct A*pcon)
{
FILE*pWrite = fopen(FILE_NAME, "w");
if (pWrite == NULL)
{
perror(pWrite);
}
for (int i = 0; i < pcon->i; i++)
{
fwrite(&(pcon->arr[i]), sizeof(struct contact), 1, pWrite);//核心语句,将结构体的内容写到到文件中
}
free(pcon->arr);//释放指针由realloc不断开辟空间的指针
fclose(pWrite);//程序运行结束前关闭文件流
}
//把文件FILE_NAME的内容加载到结构体当中
void load(struct A*pcon)
{
int n = 0;
struct contact tmp = { 0 };
FILE*fRead = fopen(FILE_NAME, "r");
if (fRead == NULL)
{
perror(fopen);
exit(EXIT_FAILURE);
}
while (fread(&tmp, sizeof(struct contact), 1, fRead))
{
check(pcon);//检查开辟的空间是否被读满
pcon->i++;
pcon->arr[n] = tmp; //核心语句读到结构体当中
n++;
}
}