实现一个通讯录;
通讯录可以用来存储1000个人的信息,每个人的信息包括:
姓名、性别、年龄、电话、住址
提供方法:
1. 添加联系人信息
2. 删除指定联系人信息
3. 查找指定联系人信息
4. 修改指定联系人信息
5. 显示所有联系人信息
6. 清空所有联系人
7. 以名字排序所有联系人
在动态版本(可见c_动态通讯录)的基础上将通讯录实现成文件存储的版本。
思想:用二进制流写入和读取文件。详细知识具体可见c_I/O文件存储
在每次退出前,写入时将整个柔性数组写入;
在每次运行操作前,读取时一次读取一个联系人结构体大小;
关于起始读取文件的联系人至柔性数组中的空间问题:在将文件存储的联系人全部读取到柔性数组中后,修改数组开辟空间的大小,使用realloc函数,完成数组空间扩充问题。详细知识具体可见c_动态内存管理
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<Windows.h>
#pragma warning(disable:4996)
#define nameSize 8
#define telSize 12
#define addrSize 20
/*
实现一个通讯录;
通讯录可以用来存储1000个人的信息,每个人的信息包括:
姓名、性别、年龄、电话、住址
提供方法:
1. 添加联系人信息
2. 删除指定联系人信息
3. 查找指定联系人信息
4. 修改指定联系人信息
5. 显示所有联系人信息
6. 清空所有联系人
7. 以名字排序所有联系人
将通讯录实现成文件存储的版本。
*/
typedef struct information{
char name[nameSize];
char sex;
int age;
char tel[telSize];
char addr[addrSize];
}Note;
typedef struct flexible{
int personNum;//当前的联系人数
Note arrNote[0];//柔性结构体数组
}fNote;
void menu()
{
printf("***************************************\n");
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("please input your choice:");
}
void myAdd(fNote *fnote, int personSum)
{
printf("please input information<name sex age tel addr>:\n");
Note note;
scanf("%s %c %d %s %s", note.name, &(note.sex), &(note.age), note.tel, note.addr);
if (personSum > fnote->personNum){
*(fnote->arrNote + (fnote->personNum)++) = note;
printf("add succeed!\n");
}
else{
printf("address book is Full!\n");
}
}
void myDelete(fNote *fnote)
{
printf("please input the person of name you want to delete:");
char tmp[nameSize];
scanf("%s", tmp);
int i = 0;
while (i < fnote->personNum){
if (!strcmp(fnote->arrNote[i].name, tmp)){
if (fnote->personNum == 1){
fnote->personNum = 0;
return;
}
//将数组添加的最后一个元素移至此覆盖当前值
fnote->arrNote[i] = *(fnote->arrNote + (fnote->personNum - 1));
(fnote->personNum)--;
printf("delete succeed!\n");
return;
}
i++;
}
printf("There is no this person!\n");
}
void myFind(fNote *fnote)
{
printf("please input the person of name you want to find:");
char tmp[nameSize];
scanf("%s", tmp);
int i = 0;
while (i < fnote->personNum){
if (!strcmp(fnote->arrNote[i].name, tmp)){
printf("name:%-10ssex:%-5cage:%-5dtel:%-15saddr:%-22s\n", fnote->arrNote[i].name, \
fnote->arrNote[i].sex, fnote->arrNote[i].age, fnote->arrNote[i].tel, fnote->arrNote[i].addr);
return;
}
i++;
}
printf("There is no this person!\n");
}
void myModify(fNote *fnote)
{
printf("please input the person of name you want to modify:");
char tmp[nameSize];
scanf("%s", tmp);
int i = 0;
while (i < fnote->personNum){
if (!strcmp(fnote->arrNote[i].name, tmp)){
printf("please input information<name sex age tel addr>:\n");
scanf("%s %c %d %s %s", fnote->arrNote[i].name, &(fnote->arrNote[i].sex), \
&(fnote->arrNote[i].age), fnote->arrNote[i].tel, fnote->arrNote[i].addr);
printf("modify succeed!\n");
return;
}
i++;
}
printf("There is no this person!\n");
}
void myShow(fNote *fnote)
{
int i = 0;
if (!fnote->personNum){
printf("no one!\n");
}
while (i < fnote->personNum){
printf("name:%-10ssex:%-5cage:%-5dtel:%-15saddr:%-22s\n", fnote->arrNote[i].name, \
fnote->arrNote[i].sex, fnote->arrNote[i].age, fnote->arrNote[i].tel, fnote->arrNote[i].addr);
i++;
}
}
void myClear(fNote *fnote)
{
fnote->personNum = 0;
printf("clear succeed!\n");
}
int myCmpNote(const void * note1, const void *note2)
{
Note *x = (Note *)note1;
Note *y = (Note *)note2;
int res = strcmp((*x).name, (*y).name);
if (res > 0){
return 1;
}
else if (res < 0){
return -1;
}
else{
return 0;
}
}
void mySort(fNote *fnote)
{
int tmp = fnote->personNum;
qsort(fnote->arrNote, tmp, sizeof(Note), myCmpNote);
myShow(fnote);
}
void branch(fNote *fnote, int sel, int personSum)
{
switch (sel){
case 1:
myAdd(fnote, personSum);
break;
case 2:
myDelete(fnote);
break;
case 3:
myFind(fnote);
break;
case 4:
myModify(fnote);
break;
case 5:
myShow(fnote);
break;
case 6:
myClear(fnote);
break;
case 7:
mySort(fnote);
break;
default:
perror("switch error");
}
}
void saveFile(fNote *fnote)
{
FILE *pFile = fopen("addressBook.txt", "wb");
if (!pFile){
perror("file open error");
exit(1);
}
fwrite(fnote->arrNote, sizeof(Note)*(fnote->personNum), 1, pFile);//将整个结构体数组一次写入文件
fclose(pFile);
}
void loadFile(fNote *fnote)
{
FILE *pFile = fopen("addressBook.txt", "rb");
if (!pFile){
perror("file open error");
exit(1);
}
for (int i = 0; fread(&(fnote->arrNote[i]), sizeof(Note), 1, pFile) == 1; i++){
fnote->personNum++;
}
fclose(pFile);
}
int main()
{
int personSum = 0;//代表可以添加的联系人数
printf("Please enter the number of people to add first:");
scanf("%d", &personSum);
fNote *fnote;
fnote = (fNote *)malloc(sizeof(fNote) + personSum *sizeof(Note));
if (fnote){
fnote->personNum = 0;
loadFile(fnote);
fNote *tmp = realloc(fnote, sizeof(fNote) + (personSum + fnote->personNum)*sizeof(Note));//扩展fnote空间,加上文件中的联系人
if (tmp){
fnote = tmp;
personSum += fnote->personNum;
}
int sel;
do{
menu();
scanf("%d", &sel);
system("cls");
if (!sel){
saveFile(fnote);//退出之前写入文件
exit(EXIT_FAILURE);
}
else if (sel > 7 && sel < 0){
printf("enter error!please try again:[0,7]");
}
else{
branch(fnote, sel, personSum);
}
} while (1);
}
free(fnote);
fnote = NULL;
system("pause");
return 0;
}
测试结果:在文件无内容时,运行程序,添加两个联系人(显示所有),然后退出(0)
查看文件内容:(以二进制格式写入,所以出现乱码)
再次运行程序:不添加任何联系人,直接显示所有(5)
文件存储成功,其他功能都测试成功,具体图可见c_静态存储1000人通讯录