使用的技术:
函数数组指针
IO读写
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
//#define MAX 100
#define SIZE_NAME 20
#define DEFAULT_SZ 3 //默认初始化大小
#define ADD_SZ 2 //每次扩容大小
void save(struct Contact* ps);
void CheckCapacity(struct Contact* ps);
//---------------------
typedef struct PeoInfo {
char name[SIZE_NAME];
int age;
char sex[5];
char tele[12];
char addr[30];
}PeoInfo;
struct Contact {
struct PeoInfo* data;
//记录当前的数据量
int size;
//记录当前容器的长度
int capacity;
};
//------------------------
void menu() {
printf("******************************\n");
printf("*** 1.add 2.del ****\n");
printf("*** 3.search 4.modify ****\n");
printf("*** 5.show 6.sort ****\n");
printf("*** 7.save 0.exit ****\n");
printf("******************************\n");
}
//-------fun---------------
//
static int findByName(const struct Contact* ps, char name[SIZE_NAME]) {
int i = 0;
for (i = 0; i < ps->size; i++) {
if (0 == strcmp(ps->data[i].name, name)) {
return i;
}
}
return -1;
}
void LoadContact(struct Contact*ps){
FILE* pfread = fopen("contact.dat", "rb");
PeoInfo tmp = { 0 };
if (pfread) {
while (fread(&tmp, sizeof(PeoInfo), 1, pfread)) {
CheckCapacity(ps);
ps->data[ps->size] = tmp;
ps->size++;
}
fclose(pfread);
pfread = NULL;
return;
}
perror("LoadContact::");
}
//init_contact
void initContact(struct Contact* ps) {
//动态 初始存放DEFAULT_SZ个
ps->data = (PeoInfo*)malloc(DEFAULT_SZ * sizeof(PeoInfo));
if (ps->data) {
//空间开辟成功
ps->size = 0;
ps->capacity = DEFAULT_SZ;
//加载文件
LoadContact(ps);
}
//空间开辟失败
return;
}
//扩容
void CheckCapacity(struct Contact* ps) {
if (ps->size == ps->capacity) {
//扩容
struct PeoInfo* ptr = (struct PeoInfo*)realloc(ps->data, (ps->capacity + ADD_SZ) * sizeof(struct PeoInfo));
if (ptr) {
ps->data = ptr;
ps->capacity += ADD_SZ;
}
}
}
void insertInfo(struct Contact* ps) {
//检测当前通讯录的容量 -> 满-扩容 不满-void
CheckCapacity(ps);
printf("请输入名字:");
scanf("%s", ps->data[ps->size].name);
printf("请输入年龄:");
scanf("%d", &(ps->data[ps->size].age));
printf("请输入性别:");
scanf("%s", ps->data[ps->size].sex);
printf("请输入电话:");
scanf("%s", ps->data[ps->size].tele);
printf("请输入地址:");
scanf("%s", ps->data[ps->size].addr);
ps->size++;
printf("用户:[%-20s\t%-4d\t%-5s\t%-12s\t%-20s] >",
ps->data[ps->size - 1].name,
ps->data[ps->size - 1].age,
ps->data[ps->size - 1].sex,
ps->data[ps->size - 1].tele,
ps->data[ps->size - 1].addr);
printf("添加成功\n");
}
void showCon(const struct Contact* ps) {
if (ps->size == 0) {
printf("通讯录为空\n");
}
else {
printf("%20s\t%4s\t%5s\t%12s\t%20s\n", "name", "age", "sex", "tele", "addr");
for (int i = 0; i < ps->size; i++) {
printf("%20s\t%4d\t%5s\t%12s\t%20s\n",
ps->data[i].name,
ps->data[i].age,
ps->data[i].sex,
ps->data[i].tele,
ps->data[i].addr);
}
}
}
void deleteInfo(struct Contact* ps) {
char name[SIZE_NAME];
printf("请输入删除的用户名:>");
scanf("%s", name);
// find name locate in contact
int pos = findByName(ps, name);
if (pos == -1) {
printf("不存在此联系人\n");
}
else {
//del
printf("用户:[%20s\t%4d\t%5s\t%12s\t%20s] >",
ps->data[pos].name,
ps->data[pos].age,
ps->data[pos].sex,
ps->data[pos].tele,
ps->data[pos].addr);
int j = 0;
for (j = pos; j < ps->size - 1; j++) {
ps->data[j] = ps->data[j + 1];
}
ps->size--;
printf("删除成功\n");
}
}
void searchInfo(const struct Contact* ps) {
char name[SIZE_NAME];
printf("请输入查询的用户名:>");
scanf("%s", name);
// find name locate in contact
int pos = findByName(ps, name);
if (pos == -1) {
printf("不存在此联系人\n");
}
else {
printf("用户信息:[%20s\t%4d\t%5s\t%12s\t%20s] >",
ps->data[pos].name,
ps->data[pos].age,
ps->data[pos].sex,
ps->data[pos].tele,
ps->data[pos].addr);
printf("查询成功\n");
}
}
void modifyInfo(struct Contact* ps) {
char name[SIZE_NAME];
printf("请输入修改的用户名:>");
scanf("%s", name);
int pos = findByName(ps, name);
if (pos == -1) {
printf("不存在此联系人\n");
}
else {
printf("用户信息:[%20s\t%4d\t%5s\t%12s\t%20s] >\n",
ps->data[pos].name,
ps->data[pos].age,
ps->data[pos].sex,
ps->data[pos].tele,
ps->data[pos].addr);
printf("请输入修改的名字:");
scanf("%s", ps->data[pos].name);
printf("请输入修改的年龄:");
scanf("%d", &(ps->data[pos].age));
printf("请输入修改的性别:");
scanf("%s", ps->data[pos].sex);
printf("请输入修改的电话:");
scanf("%s", ps->data[pos].tele);
printf("请输入修改的地址:");
scanf("%s", ps->data[pos].addr);
printf("修改成功\n");
}
}
//Component
int cmp_stu_name(const void* e1, const void* e2) {
return strcmp(((struct PeoInfo*)e1)->name, ((struct PeoInfo*)e2)->name);
}
int cmp_stu_age(const void* e1, const void* e2) {
return ((struct PeoInfo*)e1)->age - ((struct PeoInfo*)e2)->age;
}
int cmp_stu_tele(const void* e1, const void* e2) {
return strcmp(((struct PeoInfo*)e1)->tele, ((struct PeoInfo*)e2)->tele);
}
int cmp_stu_addr(const void* e1, const void* e2) {
return strcmp(((struct PeoInfo*)e1)->addr, ((struct PeoInfo*)e2)->addr);
}
void sort(struct Contact* ps) {
int sz = ps->size;
qsort(ps->data, sz, sizeof(ps->data[0]), cmp_stu_name);
printf("排序完成\n");
}
void exitCon(struct Contact* ps) {
save(ps);
printf("已退出通讯录");
//free
free(ps->data);
ps->data = NULL;
//ps不是动态开辟的,不用free
}
void save(struct Contact* ps) {
FILE* pfWrite = fopen("contact.dat", "wb");
if (pfWrite) {
for (int i = 0; i < ps->size; i++) {
fwrite(&(ps->data[i]), sizeof(PeoInfo), 1, pfWrite);
}
fclose(pfWrite);
pfWrite = NULL;
return;
}
perror("保存失败");
}
void main() {
int input = 0;
//contact -> data * size capacity
struct Contact con;
initContact(&con);
//0->非法访问0号地址,失败退出
void(*pfArr[8])(struct Contact*) = { exitCon ,insertInfo,deleteInfo,searchInfo,modifyInfo,showCon,sort,save };
do {
menu();
printf("choice:>");
input = 0;
scanf("%d", &input);
pfArr[input](&con);
} while (input);
}