#pragma once//只定义一次
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<windows.h>
#include<errno.h>
#define MAX_name 20
#define MAX_sex 5
#define MAX_telephone 13
#define MAX_address 30
#define MAX_add sizeof(FriInfo)//一个数组占内存大小
#define FunNum 6//功能个数
typedef struct FriInfo {//用户信息
char name[MAX_name];
int age;
char sex[MAX_sex];
char telephone[MAX_telephone];
char address[MAX_address];
}FriInfo;
typedef struct contact {
int size;//通讯录个数
FriInfo* con;
}contact;
void menu();//菜单界面
void InitContact(contact* con);//初始化
void AddContact(contact* con);//添加好友信息
void DeleteContact(contact* con);//删除好友信息
void SearchContact(const contact* con);//查找好友
void Modify(contact* con);//修改好友信息
void ShowContact(const contact* con);//展示好友信息
void ArrangeContact(contact* con);//排列好友信息
void Save(contact* con);//保存文件
contact.h文件
#define _CRT_SECURE_NO_WARNINGS 1
#include"contact.h"
int main() {
int input = -1;
contact con ={0};
InitContact(&con);
do {
input = -1;
system("cls");
menu();//菜单
printf("请选择:>");
scanf_s("%d", &input);
rewind(stdin);
void(*arr[7])(contact*) = { AddContact,DeleteContact,SearchContact,Modify,ShowContact,ArrangeContact };//函数选择
if (input >= 1 && input <= FunNum)
{
system("cls");
(*(arr + input - 1))(&con);
}
else if (input == 0)
{
printf("退出通讯录\n");
}
else
{
printf("选择错误,请重新输入\n");
Sleep(1500);
}
} while (input);
Save(&con);
free(con.con);
con.con = NULL;
return 0;
}
test.c文件
#define _CRT_SECURE_NO_WARNINGS 1
#include"contact.h"
void menu() {//菜单界面
printf("*********************************************\n");
printf("*******1.添加好友信息 2.删除好友信息*******\n");
printf("*******3.查找好友 4.修改好友信息*******\n");
printf("*******5.展示 6.排列 *******\n");
printf("*******0.退出 *******\n");
printf("*********************************************\n");
}
static void Print(const contact* con,int i) {//展示好友信息
printf("名字:%s\n", (*(con->con + i)).name);
printf("年龄:%d\n", (*(con->con + i)).age);
printf("性别:%s\n", (*(con->con + i)).sex);
printf("电话:%s\n", (*(con->con + i)).telephone);
printf("地址:%s\n", (*(con->con + i)).address);
}
static void PrintList(const contact* con) {//展示好友列表
for (int i = 0; i < con->size; i++) {
printf("%d.%s\n", i + 1, (*(con->con + i)).name);
}
}
int NameCompare(const void* str, const void* str2) {
FriInfo* sp = (FriInfo*)str;
FriInfo* sp2 = (FriInfo*)str2;
return strcmp(sp->name, sp2->name);
}
int AgeCompare(const void* str, const void* str2) {
FriInfo* sp = (FriInfo*)str;
FriInfo* sp2 = (FriInfo*)str2;
return sp->age - sp2->age;
}
int SexCompare(const void* str, const void* str2) {
FriInfo* sp = (FriInfo*)str;
FriInfo* sp2 = (FriInfo*)str2;
return strcmp(sp->sex, sp2->sex);
}
void InitContact(contact* con) {
FriInfo tmp;
FILE* pf = fopen("contact.dat", "rb");
if (pf == NULL) {
printf("InitContactmistake:%s\n", strerror(errno));
return;
}
while (fread(&tmp, sizeof(FriInfo), 1, pf))
{
if (ferror(pf))
perror("Read error");
FriInfo* ps = (FriInfo*)realloc(con->con, (con->size + 1) * MAX_add);
if (ps == NULL) {
printf("%s\n", strerror(errno));
return;
}
con->con = ps;
con->con[con->size] = tmp;
con->size++;
}
fclose(pf);
pf = NULL;
}
void AddContact(contact* con) {//添加好友信息
FriInfo* ps = (FriInfo*)realloc(con->con, (con->size + 1) * MAX_add);//修改数组大小
if (ps == NULL) {
printf("%s\n", strerror(errno));
}
else{
con->con = ps;
printf("请输入添加好友姓名:>");//添加好友姓名
gets_s((*(con->con + con->size)).name, MAX_name);
rewind(stdin);
printf("请输入添加好友年龄:>");//添加好友年龄
scanf_s("%d", &(*(con->con + con->size)).age);
rewind(stdin);
printf("请输入添加好友性别:>");//添加好友性别
gets_s((*(con->con + con->size)).sex, MAX_sex);
rewind(stdin);
printf("请输入添加好友电话:>");//添加好友电话
gets_s((*(con->con + con->size)).telephone, MAX_telephone);
rewind(stdin);
printf("请输入添加好友地址:>");//添加好友地址
gets_s((*(con->con + con->size)).address, MAX_address);
rewind(stdin);
con->size++;//计数加一
printf("添加成功\n");
Sleep(1000);
}
}
void DeleteContact(contact* con) {//删除好友信息
int Get =1;
if (con->size == 0) {//判断是否有好友
printf("通讯录为空\n");
printf("按任意键回到菜单\n");
system("pause");
}
else {
PrintList(con);
printf("\n请输入序号:>");
int a = scanf_s("%d", &Get);
rewind(stdin);
if (Get > con->size || Get <= 0 || a != 1 ) {
printf("没有找到该序号对应的人\n");
printf("按任意键回到菜单\n");
system("pause");
}
else {
for (int j = Get - 1; j < con->size; j++) {//删除操作
(con->con)[j] = (con->con)[j + 1];
}
con->size--;
FriInfo* ps = (FriInfo*)realloc(con->con, (con->size) * sizeof(FriInfo));
if (ps == NULL) {
printf("%s\n", strerror(errno));
goto back;
}
else {
con->con = ps;
}
printf("删除成功\n");
Sleep(1500);
}
back:;
}
}
void SearchContact(const contact* con) {//查找好友
char name[MAX_name] ={0};
printf("请输入要查找人的名字:>");
gets_s(name, MAX_name);
rewind(stdin);
int i = 0;
for (i = 0; i < con->size; i++)
{
if (0 == strcmp((*(con->con + i)).name,name ))
break;
}
if (i == con->size) {
printf("没有找到这个人\n");
printf("按任意键回到菜单\n");
system("pause");
}
else
{
printf("找到了,序号为:%d\n", i+1);
Print(con,i);//展示好友信息
printf("按任意键回到菜单\n");
system("pause");
}
}
void Modify(contact* con) {//修改好友信息
int Get = 0;
int i = 1;
if (con->size > 0) {
PrintList(con);
printf("请输入需要修改的好友序号:>");
int a = scanf_s("%d", &Get);
rewind(stdin);
if (Get < con->size + 1 && Get > 0 && a == 1) {
Print(con, Get - 1);
while (i)
{
printf("1.姓名\t2.年龄\t3.性别\n4.电话\t5.地址\t0.退出\n");
printf("请输入要修改信息前的序号:>");
a = scanf_s("%d", &i);
rewind(stdin);
if (a == 1) {
switch (i) {
case 1:
printf("请输入好友姓名:>");
gets_s((*(con->con + Get - 1)).name, MAX_name);
rewind(stdin);
break;
case 2:
printf("请输入好友年龄:>");
scanf_s("%d", &(*(con->con + Get - 1)).age);
rewind(stdin);
break;
case 3:
printf("请输入好友性别:>");
gets_s((*(con->con + Get - 1)).sex, MAX_sex);
rewind(stdin);
break;
case 4:
printf("请输入好友电话:>");
gets_s((*(con->con + Get - 1)).telephone, MAX_telephone);
rewind(stdin);
break;
case 5:
printf("请输入好友地址:>");
gets_s((*(con->con + Get - 1)).address, MAX_address);
rewind(stdin);
break;
case 0:
printf("退出成功\n");
goto b;
break;
default:
printf("输入错误\n");
printf("按任意键继续\n");
system("pause");
break;
}
system("cls");
Print(con, Get - 1);
}
else {
printf("输入错误,请重新输入\n");
}
}
system("pause");
}
else {
printf("没有找到该序号对应的人\n");
printf("按任意键回到菜单\n");
system("pause");
}
b:;
}
else
{
printf("通讯录为空\n");
printf("按任意键回到菜单\n");
system("pause");
}
}
void ShowContact(const contact* con) {//展示好友信息
system("cls");
int Get;
if (con->size == 0) {//判断是否有好友
printf("通讯录为空\n");
printf("按任意键回到菜单\n");
system("pause");
}
else {
for (int i = 0; i < con->size; i++) {//展示好友列表
printf("%d.%s\n", i + 1, (*(con->con + i)).name);
}
printf("\n请输入序号:>");
int a = scanf_s("%d", &Get);
rewind(stdin);
if (Get > con->size || a != 1 || Get <= 0) {
printf("没有找到该序号对应的人\n");
printf("按任意键回到菜单\n");
system("pause");
}
else {
Print(con, Get - 1);//展示好友信息
printf("按任意键回到菜单\n");
system("pause");
}
}
}
void ArrangeContact(contact* con) {//排列好友信息
if (con->size > 1) {
int Get = 0;
b:
printf("1.姓名\t2.年龄\t3.性别\n");
printf("请输入按照所需排序内容的序号:>");
int a = scanf_s("%d", &Get);
rewind(stdin);
if (a == 1) {
switch (Get) {
case 1:
qsort(con->con, con->size, MAX_add, NameCompare);
break;
case 2:
qsort(con->con, con->size, MAX_add, AgeCompare);
break;
case 3:
qsort(con->con, con->size, MAX_add, SexCompare);
break;
default:
printf("输入错误,请重新输入\n");
goto b;
}
printf("排序成功\n");
Sleep(1500);
}
}
else
{
printf("通讯录内人数不足两个,无法排序\n");
printf("按任意键回到菜单\n");
system("pause");
}
}
void Save(contact* con) {
FILE* pf = fopen("contact.dat", "wb");
if (pf == NULL) {
printf("Savemistake:%s\n", strerror(errno));
return;
}
for (int i = 0; i < con->size; i++) {
fwrite(&con->con[i], sizeof(FriInfo), 1, pf);
if (ferror(pf))
perror("Write error");
}
fclose(pf);
pf = NULL;
}
contact.c文件
该简易通讯录实现支持保存到文档和读取文档