目录
contact.h头文件
contact.c源文件
main.c源文件
项目分析:
- 通讯录项目需要用到的顺序表的数据结构,每个元素为一个联系人信息结构体
- 通讯录功能有新增、删除、查找、修改、排序、打印、清空
- 通讯录还要有读档和存档的功能,用文件的读写
- 新增数据要考虑顺序容量问题,若满则扩
- 删除数据要先找到数据,再从要删除数据的位置,循环将后面的数据前移覆盖
- 查找数据用strstr比strcmp更好,这样能实现模糊查找
- 排序用qsort函数,可以按照联系人姓名或者联系人电话号码进行排序
contact.h头文件
外部头文件包含:
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <stdbool.h>
#include <Windows.h>
#include <string.h>
数据结构:
#define CAPACITY 4 //顺序表初始容量
typedef struct PeoInfo
{
char name[10];
char phone[12];
}Peo;
typedef struct Contact
{
Peo* data;
int size;
int capacity;
}Con;
函数声明:
void Init(Con* con); //初始化
void Add(Con* con); //添加
void Del(Con* con); //删除
void Find(Con* con); //查找
void Mod(Con* con); //修改
void Sort(Con* con); //排序
void Print(Con* con); //打印
void Destory(Con* con); //清空
void Load(Con* con); //加载信息
void Save(Con* con); //保存信息
contact.c源文件
void Init(Con* con) 初始化
#include "contact.h"
void Init(Con* con)
{
assert(con);
con->data = (Peo*)malloc(sizeof(Peo) * CAPACITY);
if (con->data == NULL)
{
perror("init::malloc");
exit(1);
}
con->size = 0;
con->capacity = CAPACITY;
Load(con); //读档
}
void Add(Con* con)
void Del(Con* con) 数据增删
用临时变量结构体指针进行扩容,增加安全性
bool Empty(Con* con)
{
assert(con);
return con->size == 0;
} //判空
void Check(Con* con)
{
assert(con);
if (con->size == con->capacity)
{
Peo* tmp = (Peo*)realloc(con->data, sizeof(Peo) * (con->size + CAPACITY));
if (tmp)
{
con->data = tmp;
con->capacity += CAPACITY;
}
}
} //检查容量
void Add(Con* con)
{
assert(con);
Check(con);
printf("请输入姓名:");
scanf("%s", con->data[con->size].name);
printf("请输入号码:");
scanf("%s", con->data[con->size].phone);
printf("新增联系人成功:%s %s\n", con->data[con->size].name, con->data[con->size].phone);
++con->size;
}
void Del(Con* con)
{
assert(con);
if (Empty(con))
{
printf("通讯录为空\n");
return;
}
printf("请输入要删除的联系人姓名:");
char del[20];
scanf("%s", del);
int i = 0;
while (i < con->size)
{
if (strcmp(del, con->data[i].name) == 0)
{
int j = i;
while (j < con->size - 1)
{
strcpy(con->data[j].name, con->data[j + 1].name);
strcpy(con->data[j].phone, con->data[j + 1].phone);
++j;
}
}
++i;
}
}
void Find(Con* con) 模糊查询
void Find(Con* con)
{
assert(con);
printf("请输入姓名/号码进行查询:");
char find[20];
scanf("%s", find);
int count = 0;
int i = 0;
while (i < con->size)
{
if (strstr(con->data[i].name, find) || strstr(con->data[i].phone, find))
{
printf("%10s %12s\n", con->data[i].name, con->data[i].phone);
++count;
}
++i;
}
printf("共查询到 %d 条数据\n", count);
}
void Mod(Con* con) 数据修改
void Mod(Con* con)
{
assert(con);
printf("请输入需要修改信息的联系人姓名:");
char mod[20];
scanf("%s", mod);
int i = 0;
while (i < con->size)
{
if (strcmp(mod, con->data[i].name) == 0)
{
printf("请更新姓名:");
scanf("%s", con->data[i].name);
printf("请更新号码:");
scanf("%s", con->data[i].phone);
return;
}
++i;
}
printf("联系人未查询到\n");
}
void Sort(Con* con) 数据排序
int cmp_name(const void* e1, const void* e2)
{
return strcmp((*(Peo*)e1).name, (*(Peo*)e2).name);
}
int cmp_phone(const void* e1, const void* e2)
{
return strcmp((*(Peo*)e1).phone, (*(Peo*)e2).phone);
}
void Sort(Con* con)
{
assert(con);
printf("请选择排序方式(1.cmp_name 2.cmp_phone):");
int choose;
scanf("%d", &choose);
if (choose == 1)
{
qsort(con->data, con->size, sizeof(Peo), cmp_name);
printf("已按姓名排序成功\n");
}
else if (choose == 2)
{
qsort(con->data, con->size, sizeof(Peo), cmp_phone);
printf("已按号码排序成功\n");
}
else
{
printf("输入错误,排序失败\n");
}
}
void Print(Con* con) 打印
void Destory(Con* con) 销毁、清空
void Print(Con* con)
{
assert(con);
if (Empty(con))
{
printf("通讯录为空\n");
return;
}
int i = 0;
printf(" 联系人 电话号码\n");
while (i < con->size)
{
printf("%03d: %10s %12s\n", i, con->data[i].name, con->data[i].phone);
++i;
}
}
void Destory(Con* con)
{
assert(con);
free(con->data);
con->data = (Peo*)malloc(sizeof(Peo) * CAPACITY);
if (con->data == NULL)
{
perror("destory::malloc");
exit(1);
}
con->size = 0;
con->capacity = CAPACITY;
}
void Load(Con* con) 读档
void Save(Con* con) 存档
void Load(Con* con)
{
assert(con);
FILE* pfRead = fopen("contact.txt", "rb");
if (pfRead == NULL)
return;
Peo tmp = { 0 };
while (fread(&tmp, sizeof(Peo), 1, pfRead))
{
Check(con);
con->data[con->size] = tmp;
++con->size;
}
fclose(pfRead);
pfRead = NULL;
}
void Save(Con* con)
{
assert(con);
FILE* pfWrite = fopen("contact.txt", "wb");
if (pfWrite == NULL)
{
perror("pfWrite::fopen");
exit(1);
}
int i = 0;
while (i < con->size)
{
fwrite(con->data + i, sizeof(Peo), 1, pfWrite);
++i;
}
fclose(pfWrite);
pfWrite = NULL;
}
main.c源文件
#include "contact.h"
void Menu()
{
printf("\n------------------------\n");
printf("----- 0. 退出 -----\n");
printf("----- 1. 新增 -----\n");
printf("----- 2. 删除 -----\n");
printf("----- 3. 查找 -----\n");
printf("----- 4. 修改 -----\n");
printf("----- 5. 排序 -----\n");
printf("----- 6. 打印 -----\n");
printf("----- 7. 清空 -----\n");
printf("------------------------\n");
printf("请输入选项:");
}
int main()
{
Con con;
Init(&con);
int input;
do
{
Menu();
scanf("%d", &input);
system("cls");
switch (input)
{
case 0:
Save(&con);
printf("退出通讯录\n");
return;
case 1:
Add(&con);
break;
case 2:
Del(&con);
break;
case 3:
Find(&con);
break;
case 4:
Mod(&con);
break;
case 5:
Sort(&con);
break;
case 6:
Print(&con);
break;
case 7:
Destory(&con);
break;
default:
break;
}
} while (input);
return 0;
}