基于上一个通讯录,改写了一个可以动态存储的版本,在原始存储人数的基础上,每次只要超出了存储范围,就在堆上开辟新的空间。
1、contact.h
#ifndef _CONTACT_H_
#define __CONTACT_H_
#include<stdio.h>
#include<windows.h>
#include<stdlib.h>
#include<assert.h>
#include<string.h>
#include<malloc.h>
#pragma warning (disable:4996)
#define SIZE 128
#define TOTAL 15
#define INC_COUNT 10
//姓名、性别、年龄、电话、住址
typedef struct person{
char name[SIZE / 4];
char sex;//f,m
int age;
char telphone[SIZE / 4];
char address[SIZE];
}person_t;
typedef struct contact{
int size;//当前有多少人
int cap;//总容量有多少人
person_t persons[0];
}contact_t;
void Init_contact(contact_t **ct);
void AddPerson(contact_t **ct);
void DeletePerson(contact_t *ct);
//index :-1 :show all
//index>=0 : show index person
void ShowContact(contact_t *ct,int index);
void SearchPerson(contact_t *ct);
void ModPerson(contact_t *ct);
void ClsContact(contact_t *ct);
void SortContact(contact_t *ct);
void destory(contact_t **ct);
#endif
2、contact.c
#include"contact.h"
#include"contact.h"
static int IsFull(contact_t *ct){
assert(ct);
return ct->size == ct->cap;
}
static int IsExist(contact_t *ct, const char *telphone){
assert(telphone);
person_t *end = ct->persons + ct->size;
int index = 0;
for (person_t *p = ct->persons; p < end; p++, index++){
if (0 == strcmp(p->telphone, telphone)){
return index;
}
}
return -1;
}
static int IsNameExist(contact_t *ct, const char *name){
assert(name);
person_t *end = ct->persons + ct->size;
int index = 0;
for (person_t *p = ct->persons; p < end; p++, index++){
if (0 == strcmp(p->name, name)){
return index;
}
}
return -1;
}
static void SearchPersonTelHelper(contact_t *ct){
assert(ct);
char search_key[SIZE / 4];
printf("请输入你要查找人的电话号码# ");
scanf("%s", search_key);
int index = IsExist(ct, search_key);
if (-1 == index)
{
printf("你要查找的人[%s]不存在!\n", search_key);
return;
}
else{
ShowContact(ct, index);
}
}
static void SearchPersonNameHelper(contact_t *ct){
assert(ct);
char search_key[SIZE / 4];
printf("请输入你要查找人的姓名# ");
scanf("%s", search_key);
int index = IsNameExist(ct, search_key);
if (-1 == index)
{
printf("你要查找的人[%s]不存在!\n", search_key);
return;
}
else{
ShowContact(ct, index);
}
}
static int CompPerson(const void *x, const void *y)
{
person_t *x_p = (person_t *)x;
person_t *y_p = (person_t *)y;
return strcmp(x_p->name, y_p->name);
}
void Init_contact(contact_t **ct)
{
*ct =(contact_t * )malloc(sizeof(contact_t)+TOTAL*sizeof(person_t));
if (NULL==*ct)
{
printf("malloc error\n");
exit(EXIT_FAILURE);
}
(*ct)->size = 0;
(*ct)->cap= TOTAL;
}
static int Inc(contact_t **ct){
assert(*ct);
int ret = 0;
contact_t *p = (contact_t *)realloc(*ct, sizeof(contact_t) + sizeof(person_t)*((*ct)->cap + INC_COUNT));
if (NULL != p){
printf("realloc success!\n");
*ct = p;
(*ct)->cap += INC_COUNT;
ret = 1;
}
return ret;
}
void AddPerson(contact_t **ct){
assert(*ct);
char de_key[SIZE / 4];
printf("请输入你要添加人的电话号码#");
scanf("%s", de_key);
if ((IsExist((*ct),de_key))>=0){
printf("该用户[%s]已经存在!\n",de_key);
return;
}
else {
printf("添加新联系人!\n");
}
if (!IsFull(*ct) || Inc(ct)){
person_t *p = (*ct)->persons + (*ct)->size;
printf("姓名# ");
scanf(" %s", p->name);
printf("电话# ");
scanf(" %s", p->telphone);
printf("性别# ");
scanf(" %c", &(p->sex));
printf("年龄# ");
scanf(" %d", &(p->age));
printf("地址# ");
scanf(" %s", p->address);
(*ct)->size += 1;
printf("....add success!\n");
}
else{
printf("realloc error!\n");
}
}
void DeletePerson(contact_t *ct){
assert(ct);
char de_key[SIZE / 4];
printf("请输入你要删除人的电话号码# ");
scanf("%s", de_key);
int index = 0;
if ((index = IsExist(ct, de_key)) >= 0){
ct->persons[index] = ct->persons[ct->size - 1];
ct->size -= 1;
printf("delete success!\n");
}
else{
printf("你要删除的用户[%s],是不存在的!\n", de_key);
}
}
void SearchPerson(contact_t *ct){
assert(ct);
printf("#######################\n");
printf("#1.按照姓名 2.按照电话#\n");
printf("#######################\n");
printf("select:>");
int select = 0;
scanf("%d", &select);
switch (select){
case 1:
SearchPersonNameHelper(ct);
break;
case 2:
SearchPersonTelHelper(ct);
break;
}
}
void ModPerson(contact_t *ct){
assert(ct);
char de_key[SIZE / 4];
printf("请输入你要修改人的姓名# ");
scanf("%s", de_key);
int pos = IsNameExist(ct,de_key);
if (-1 == pos){
printf("要修改的人不存在!\n");
}
else
{
printf("请修改名字:>");
scanf(" %s", ct->persons[pos].name);
printf("请修改电话:>");
scanf(" %s", ct->persons[pos].telphone);
printf("请修改性别:>");
scanf(" %c", &(ct->persons[pos].sex));
printf("请修改年龄:>");
scanf(" %d", &(ct->persons[pos].age));
printf("请修改地址:>");
scanf(" %s", ct->persons[pos].address);
printf("修改成功!\n");
}
}
void ShowContact(contact_t *ct,int index)
{
assert(ct);
if (-1 == index){
person_t *end = ct->persons + ct->size;
printf("统计:%d/%d\n", ct->size, ct->cap);
printf("-----------------------------------------------\n");
for (person_t *p = ct->persons; p < end; p++){
printf("|%-8s|%-2c|%-3d|%-11s|%-10s|\n",
p->name, p->sex, p->age, p->telphone, p->address);
}
printf("-----------------------------------------------\n");
}
else{
person_t *p = ct->persons + index;
printf("|%-8s|%-2c|%-3d|%-11s|%-10s|\n",
p->name, p->sex, p->age, p->telphone, p->address);
}
}
void ClsContact(contact_t *ct)
{
assert(ct);
ct->size = 0;
}
void SortContact(contact_t *ct)
{
assert(ct);
qsort(ct->persons, ct->size, sizeof(person_t), CompPerson);
}
void destory(contact_t **ct)
{
free(*ct);
(*ct) = NULL;
}
3、main.c
#include"contact.h"
#include"contact.h"
static void Menu()
{
printf("############################\n");
printf("# 1.Add 2.Del #\n");
printf("# 3.Search 4.Mod #\n");
printf("# 5.Show 6.Cls #\n");
printf("# 7.Sort 8.Quit #\n");
printf("############################\n");
printf("Please Select:>");
}
int main()
{
contact_t *ct=NULL;
Init_contact(&ct);
int quit = 0;
int select = 0;
while (!quit)
{
Menu();
scanf("%d", &select);
switch (select){
case 1://Add
AddPerson(&ct);
break;
case 2:
DeletePerson(ct);
break;
case 3:
SearchPerson(ct);
break;
case 4:
ModPerson(ct);
break;
case 5:
ShowContact(ct, -1);
break;
case 6:
ClsContact(ct);
break;
case 7:
SortContact(ct);
break;
default:
quit = 1;
printf("正在退出...\n");
break;
}
}
system("pause");
return 0;
}