核心
- 多了一个每次增加容量的大小的宏
- 在添加前/删除后/读入后, 需要检查容量, 是否需要增加 / 减少容量
- 动态开辟 / 内存释放 malloc() / free()
实现
#ifndef __contact_h__
#define __contact_h__
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
//初始容量大小
#define MAX_NUM 1
//每次增加容量的大小
#define INCREASE_NUM 1
#define MAX_NAME 24
#define MAX_SEX 10
#define MAX_TEL 20
#define MAX_ADDRESS 20
//个人信息
typedef struct People{
char name[MAX_NAME];
char sex[MAX_SEX];
char age;
char tel[MAX_TEL];
char address[MAX_ADDRESS];
} Peo;
//保存多个个人信息
typedef struct Contact{
int count;//已存数目
Peo *con;//**与静态不同,这里需要改成指针**
int max_size;//**当前最大容量**
} Con;
//选项
enum Choice{
EXIT,
ADD,
DEL,
SEARCH,
MOD,
SHOW,
EMPTY,
NAMESORT,
SAVE,
LOAD
};
//函数声明
void initContact(Con* pcon);//初始化
void add(Con* pcon);//添加
void del(Con* pcon);//删除
void search(Con* pcon);//查找
void mod(Con* pcon);//修改
void show(Con* pcon);//展示
void empty(Con* pcon);//清空
void namesort(Con* pcon);//按名字排序
void save(Con* pcon);//保存到文件中
void load(Con* pcon);//从文件中载入
#endif __contact_h__
#include "m.h"
//初始化(动态开辟)
void initContact(Con* pcon){
//malloc开辟
pcon->con = (Peo*)malloc(MAX_NUM * sizeof(Peo));
pcon->count = 0;
pcon->max_size = MAX_NUM;
memset(pcon->con, 0, MAX_NUM * sizeof(Peo));
printf("初始化成功!\n");
}
//检查容量/增容函数
static void CheckIncrease(Con* pcon){
//需要增加容量的情况
if (pcon->count == pcon->max_size){
printf("通讯录已满!\n");
//realloc 重新开辟
pcon->con = (Peo*)realloc(pcon->con, (pcon->max_size + INCREASE_NUM) * sizeof(Peo));
//把 max_size 变成增加容量后的大小
pcon->max_size = pcon->max_size + INCREASE_NUM;
if (pcon != NULL){
printf("增加容量成功!\n");
}
}
//需要减少容量的情况
if (pcon->count < pcon->max_size - INCREASE_NUM){
//减容
pcon->con = (Peo*)realloc(pcon->con, (pcon->max_size - INCREASE_NUM) * sizeof(Peo));
printf("减容成功\n");
}
}
//添加联系人(是否需要增加容量)
void add(Con* pcon){
//count 代表已经存放的联系人的个数
//max_size 代表当前最大容量
if (pcon->con == NULL){//在清空操作的时候,把 pcon->con = NULL;了
initContact(pcon);//检查容量
}
CheckIncrease(pcon);
printf("请输入姓名 :");
scanf("%s", pcon->con[pcon->count].name);
printf("请输入性别 :");
scanf("%s", pcon->con[pcon->count].sex);
printf("请输入年龄 :");
scanf("%d", &(pcon->con[pcon->count].age));
printf("请输入电话 :");
scanf("%s", pcon->con[pcon->count].tel);
printf("请输入地址 :");
scanf("%s", pcon->con[pcon->count].address);
pcon->count++;
printf("添加成功!\n");
}
//删除(删除之后,总容量是否需要减容)
void del(Con* pcon){
if (pcon->count == 0){
printf("通讯录已空!\n");
return;
}
char name[MAX_NAME] = { 0 };
printf("请输入要删除联系人的姓名 :");
scanf("%s", name);
int i = 0;
for (i = 0; i < pcon->count; i++){
if (strcmp(name, pcon->con[i].name) == 0){
int j = 0;
for (j = i; j < pcon->count - 1; j++){//把联系人依次往前挪
pcon->con[j] = pcon->con[j + 1];
}
pcon->count--;
printf("找到联系人,并删除成功!\n");
CheckIncrease(pcon);//检查容量
return;
}
}
if (i == pcon->count){
printf("未找到该联系人,请重新输入!\n");
}
}
//查找
void search(Con* pcon){
if (pcon->count == 0){
printf("通讯录已空!\n");
return;
}
char name[MAX_NAME] = { 0 };
printf("请输入要查找联系人的姓名 :");
scanf("%s", name);
int i = 0;
for (i = 0; i < pcon->count; i++){
if (strcmp(name, pcon->con[i].name) == 0){
printf("找到联系人!\n");
printf(" %d ", i + 1);
printf("%-5s %-3s %-3d %-15s %-15s\n", pcon->con[i].name, pcon->con[i].sex
, pcon->con[i].age, pcon->con[i].tel, pcon->con[i].address);
break;
}
}
if (i == pcon->count){
printf("未找到该联系人,请重新输入!\n");
}
}
//修改
void mod(Con* pcon){
if (pcon->count == 0){
printf("通讯录已空!\n");
return;
}
char name[MAX_NAME] = { 0 };
printf("请输入要修改联系人的姓名 :");
scanf("%s", name);
int i = 0;
for (i = 0; i < pcon->count; i++){
if (strcmp(name, pcon->con[i].name) == 0){
printf("找到联系人!\n");
printf("请输入姓名 :");
scanf("%s", pcon->con[i].name);
printf("请输入性别 :");
scanf("%s", pcon->con[i].sex);
printf("请输入年龄 :");
scanf("%d", &(pcon->con[i].age));
printf("请输入电话 :");
scanf("%s", pcon->con[i].tel);
printf("请输入地址 :");
scanf("%s", pcon->con[i].address);
printf("修改成功!\n");
break;
}
}
if (i == pcon->count){
printf("未找到该联系人,请重新输入!\n");
}
}
//展示
void show(Con* pcon){
if (pcon->count == 0){
printf("通讯录已空!\n");
return;
}
printf("当前最大容量 : %d\n", pcon->max_size);
printf("当前已使用容量 : %d\n", pcon->count);
int i = 0;
printf(" %-5s %-3s %-3s %-15s %-15s\n", "姓名", "性别", "年龄", "电话", "住址");
for (i = 0; i < pcon->count; i++){
printf(" %d ", i + 1);
printf("%-5s %-3s %-3d %-15s %-15s\n", pcon->con[i].name, pcon->con[i].sex
, pcon->con[i].age, pcon->con[i].tel, pcon->con[i].address);
}
}
//清空(free)
void empty(Con* pcon){
if (pcon->count == 0){
printf("通讯录已空!\n");
return;
}
pcon->count = 0;
pcon->max_size = MAX_NUM;
printf("清空成功");
}
//按名字排序
void namesort(Con* pcon){
if (pcon->count == 0){
printf("通讯录已空!\n");
return;
}
int i = 0;
int j = 0;
for (i = 0; i < pcon->count - 1; i++){
for (j = 0; j < pcon->count - i - 1; j++){
if (strcmp(pcon->con[i].name, pcon->con[i + 1].name) > 0){
Peo tmp = pcon->con[i];
pcon->con[i] = pcon->con[i + 1];
pcon->con[i + 1] = tmp;
}
}
}
printf("排序成功!\n");
show(pcon);
}
//保存到文件里
void save(Con* pcon){
if (pcon->count == 0){
printf("通讯录已空!\n");
return;
}
FILE* fp = fopen("contact.text", "w");
assert(fp);
int i = 0;
for (i = 0; i < pcon->count; i++){
fprintf(fp, "%-5s %-3s %-3d %-15s %-15s\n", pcon->con[i].name, pcon->con[i].sex
, pcon->con[i].age, pcon->con[i].tel, pcon->con[i].address);
}
printf("写入成功!\n");
fclose(fp);
fp = NULL;
}
//从文件里读入(每次读入之后都要需要检查容量)
void load(Con* pcon){
FILE* fp = fopen("contact.text", "r");
if (fp == NULL){
printf("没有文件\n");
}
int i = 0;
//fgetc() != EOF 或 fgets() != NULL检测是否到达文件末尾
//feof()判断是否到达文件末尾
for (i = pcon->count; !feof(fp); i++){
//格式化输入,中间的数字代表一次输入几个字符
fscanf(fp, "%5s %3s %3d %15s %15s", pcon->con[i].name, pcon->con[i].sex
, &(pcon->con[i].age), pcon->con[i].tel, pcon->con[i].address);
pcon->count++;
CheckIncrease(pcon);//检查容量函数
}
pcon->count--;
printf("读入成功!\n");
show(pcon);
fclose(fp);
fp = NULL;
}
#include "m.h"
void menu(){
printf("********************************************************\n");
printf("*****1. add 2. del 3. search 4. mod******************\n");
printf("*****5. show 6. empty 7. nameSort 8. save 9 .load*******\n");
printf("********************************************************\n");
}
int main() {
menu();
Con con;
initContact(&con);//初始化
assert(&con != NULL);
while (1){
int choice = 0;
printf("请输入操作: ");
scanf("%d", &choice);
switch (choice){
case ADD:
add(&con);
break;
case DEL:
del(&con);
break;
case SEARCH:
search(&con);
break;
case MOD:
mod(&con);
break;
case SHOW:
show(&con);
break;
case EMPTY:
empty(&con);
break;
case NAMESORT:
namesort(&con);
break;
case SAVE:
save(&con);
break;
case LOAD:
load(&con);
break;
case EXIT:
printf("退出成功!\n");
break;
default:
break;
}
}
return 0;
}