文章目录
- 相关知识
- 1. contacts.h 头文件、函数/常量/结构体声明
- 2. test.c 主界面菜单打印、菜单功能选项选择
- 3. contacts.c 函数实现
- 4. 实现时该注意的地方
相关知识
- 结构体
文章:计算结构体的大小!结构体内存对齐的意义是什么?
文章:结构体自引用与传参原则
- 动态内存(核心)
文章:指针与动态内存
- 枚举
文章:为什么建议使用枚举而不是#define?
- 函数指针与void*指针
文章:利用void*、函数指针回调函数,模仿库函数qsort()将排序算法通用化,可以对任何数据排序。
1. contacts.h 头文件、函数/常量/结构体声明
#pragma once
#include
#include
#include
#include
#include
#define NAME_LEN 15
#define ADDR_LEN 25
#define DEFAULT_CAPACITY 3
typedef struct PeopleInfo
{
char gender;
short age;
char tele[11];
char* name;
char* addr;
} PeopleInfo;
typedef struct Contacts
{
PeopleInfo* peopleInfo;
int peopleNums;
int capacity;
} Contacts;
void InitContacts(Contacts* contacts);
void AddContacts(Contacts* contacts);
int SearchContactsByName(Contacts* contacts);
void ShowAllContacts(Contacts* contacts);
void ModifyByName(Contacts* contacts);
void DeleteContacts(Contacts* contacts);
void SortContacts(Contacts* contacts);
void DestroyContacts(Contacts* contacts);
2. test.c 主界面菜单打印、菜单功能选项选择
#define _CRT_SECURE_NO_WARNINGS 1
#include "contacts.h"
static void menu()
{
printf("\n----- OPTIONS ----- OPTIONS ----- OPTIONS -----\n");
printf(" ************** 1.ADD ********************* \n");
printf(" ************** 2.DELETE ****************** \n");
printf(" ************** 3.SEARCH ****************** \n");
printf(" ************** 4.MODIFY ****************** \n");
printf(" ************** 5.SHOW ALL **************** \n");
printf(" ************** 6.DELETE ALL ************** \n");
printf(" ************** 7.SORT ******************** \n");
printf(" ************** 0.EXIT ******************** \n");
printf("----- OPTIONS ----- OPTIONS ----- OPTIONS -----\n\n");
}
enum Option
{
EXIT,
ADD,
DELETE,
SEARCH,
MODIFY,
SHOW_ALL,
DELETE_ALL,
SORT
};
int main()
{
Contacts contacts;
InitContacts(&contacts);
short input = 0;
do
{
menu();
printf("请选择:");
scanf("%hd", &input);
getchar();
switch (input)
{
case ADD:
printf("\nADD.\n");
AddContacts(&contacts);
break;
case DELETE:
printf("\nDELETE.\n");
DeleteContacts(&contacts);
break;
case SEARCH:
printf("SEARCH.\n");
printf("Who do you want to search?\n");
int index = SearchContactsByName(&contacts);
if (index < 0)
{
printf("The contacts you just searched doesn't exist in your contacts.\n\n");
}
else
{
printf("SEARCH SUCCEED!\n");
printf("| %-20s | %s | %s | %-11s | %-40s |\n",
"NAME", "GENDER", "AGE", " TELEPHONE ", "ADDRESS");
printf("------------------------------------------------------------------------------------------------\n");
printf("| %-20s | %3c | %2hd | %-11s | %-40s |\n\n",
(contacts.peopleInfo + index)->name,
(contacts.peopleInfo + index)->gender,
(contacts.peopleInfo + index)->age,
(contacts.peopleInfo + index)->tele,
(contacts.peopleInfo + index)->addr);
}
break;
case MODIFY:
printf("\nMODIFY.\n");
ModifyByName(&contacts);
break;
case SHOW_ALL:
printf("\nSHOW ALL CONTACTS.\n");
ShowAllContacts(&contacts);
break;
case DELETE_ALL:
printf("\nDELETE ALL CONTACTS.\n");
DestroyContacts(&contacts);
InitContacts(&contacts);
printf("DELETE ALL CONTACTS SUCCEED!\n\n");
break;
case SORT:
printf("\nSORT.\n");
SortContacts(&contacts);
break;
case EXIT:
printf("\nEXIT.\n");
DestroyContacts(&contacts);
break;
default:
printf("\nWRONG OPERATION.\n");
break;
}
} while (input);
return 0;
}
3. contacts.c 函数实现
#define _CRT_SECURE_NO_WARNINGS 1
#include "contacts.h"
static void initNameAndAddr(PeopleInfo* peopleInfo, int beginning, int end)
{
for (int i = beginning; i < end; i++)
{
(peopleInfo + i)->addr = (char*)calloc(ADDR_LEN, sizeof(char));
if ((peopleInfo + i)->addr == NULL)
{
perror("calloc peopleInfo->addr initPeopleInfo()");
return;
}
(peopleInfo + i)->name = (char*)calloc(NAME_LEN, sizeof(char));
if ((peopleInfo + i)->name == NULL)
{
perror("calloc peopleInfo->name initPeopleInfo()");
return;
}
}
}
void InitContacts(Contacts* contacts)
{
contacts->peopleNums = 0;
contacts->capacity = DEFAULT_CAPACITY;
contacts->peopleInfo = (PeopleInfo*)malloc(contacts->capacity * sizeof(PeopleInfo));
if (contacts->peopleInfo == NULL)
{
perror("\ncalloc PeopleInfo - InitContacts()\n");
return;
}
initNameAndAddr(contacts->peopleInfo, 0, contacts->capacity);
}
void DestroyContacts(Contacts* contacts)
{
free(contacts->peopleInfo->addr);
contacts->peopleInfo->addr = NULL;
free(contacts->peopleInfo->name);
contacts->peopleInfo->name = NULL;
free(contacts->peopleInfo);
contacts->peopleInfo = NULL;
}
static void CheckCapacity(Contacts* contacts)
{
if (contacts->peopleNums == contacts->capacity)
{
PeopleInfo* tmpPeopleInfo = realloc(contacts->peopleInfo,
((contacts->capacity + DEFAULT_CAPACITY) * sizeof(PeopleInfo)));
if (tmpPeopleInfo == NULL)
{
perror("\nrealloc peopleInfo - CheckCapacity()\n");
return;
}
else
{
contacts->peopleInfo = tmpPeopleInfo;
contacts->capacity += DEFAULT_CAPACITY;
initNameAndAddr(contacts->peopleInfo, contacts->peopleNums, contacts->capacity);
}
printf("\nENLARGE CAPACITY SUCCEED!\n");
}
}
void AddContacts(Contacts* contacts)
{
assert(contacts);
CheckCapacity(contacts);
PeopleInfo* peopleInfo = contacts->peopleInfo + contacts->peopleNums;
printf("NAME:");
scanf("%[^\n]s", peopleInfo->name);
getchar();
printf("GENDER:");
scanf("%c", &(peopleInfo->gender));
getchar();
printf("AGE:");
scanf("%hd", &(peopleInfo->age));
getchar();
printf("TELEPHONE:");
scanf("%s", peopleInfo->tele);
getchar();
printf("ADDRESS:");
scanf("%[^\n]s", peopleInfo->addr);
getchar();
(contacts->peopleNums)++;
printf("\nADD SUCCEED!\n");
}
int SearchContactsByName(Contacts* contacts)
{
char name[NAME_LEN];
printf("\nPlease enter the contacts' name:");
scanf("%[^\n]s", name);
getchar();
for (int i = 0; i < contacts->peopleNums; i++)
{
if (strcmp(name, (contacts->peopleInfo + i)->name) == 0)
{
return i;
}
}
return -1;
}
void ShowAllContacts(Contacts* contacts)
{
printf("| %-20s | %s | %s | %-11s | %-40s |\n",
"NAME", "GENDER", "AGE", " TELEPHONE ", "ADDRESS");
printf("-----------------------------------------------------------------------------------------------------\n");
for (int i = 0; i < contacts->peopleNums; i++)
{
printf("| %-20s | %3c | %2hd | %-11s | %-40s |\n",
(contacts->peopleInfo + i)->name,
(contacts->peopleInfo + i)->gender,
(contacts->peopleInfo + i)->age,
(contacts->peopleInfo + i)->tele,
(contacts->peopleInfo + i)->addr);
}
}
void ModifyByName(Contacts* contacts)
{
if (contacts->peopleNums <= 0)
{
printf("No contacts in your contacts book.\n\n");
return;
}
assert(contacts->peopleInfo);
printf("\nWhose information you want to modify?\n");
int index = SearchContactsByName(contacts);
if (index < 0)
{
printf("\nCannot find the information.\n\n");
return;
}
PeopleInfo* peopleInfo = contacts->peopleInfo + index;
printf("\nORIGINAL INFORMATION:\n");
printf("| %-20s | %s | %s | %-11s | %-40s |\n",
"NAME", "GENDER", "AGE", " TELEPHONE ", "ADDRESS");
printf("------------------------------------------------------------------------------------------------\n");
printf("| %-20s | %3c | %2hd | %-11s | %-40s |\n\n",
peopleInfo->name,
peopleInfo->gender,
peopleInfo->age,
peopleInfo->tele,
peopleInfo->addr);
printf("----- MODIFICATION OPTIONS ----- \n");
printf(" *********** 1.NAME *********** \n");
printf(" *********** 2.GENDER *********** \n");
printf(" *********** 3.AGE *********** \n");
printf(" *********** 4.TELEPHONE *********** \n");
printf(" *********** 5.ADDRESS *********** \n");
printf(" *********** 0.EXIT MODIFICATION *********** \n");
printf("----- MODIFICATION OPTIONS ----- \n\n");
short input;
do
{
printf("What information you want to modify?(Or 0 to exit):");
scanf("%hd", &input);
getchar();
switch (input)
{
case 0:
printf("\nEXIT MODIFICATION.\n");
break;
case 1:
printf("\nMODIFY NAME:");
scanf("%[^\n]s", peopleInfo->name);
getchar();
break;
case 2:
printf("\nMODIFY GENDER:");
scanf("%c", &(peopleInfo->gender));
getchar();
break;
case 3:
printf("\nMODIFY AGE:");
scanf("%hd", &(peopleInfo->age));
getchar();
break;
case 4:
printf("\nMODIFY TELEPHONE:");
scanf("%s", peopleInfo->tele);
getchar();
break;
case 5:
printf("\nMODIFY ADDRESS:");
scanf("%[^\n]s", peopleInfo->addr);
getchar();
break;
default:
printf("\nWRONG OPERATION.\n");
break;
}
} while (input);
printf("\nMODIFIED INFORMATION:\n");
printf("| %-20s | %s | %s | %-11s | %-40s |\n",
"NAME", "GENDER", "AGE", " TELEPHONE ", "ADDRESS");
printf("------------------------------------------------------------------------------------------------\n");
printf("| %-20s | %3c | %2hd | %-11s | %-40s |\n\n",
peopleInfo->name,
peopleInfo->gender,
peopleInfo->age,
peopleInfo->tele,
peopleInfo->addr);
printf("\nMODIFY SUCCEED!\n");
}
void DeleteContacts(Contacts* contacts)
{
if (contacts->peopleNums <= 0)
{
printf("You don't have any contacts.\n\n");
return;
}
assert(contacts->peopleInfo);
ShowAllContacts(contacts);
printf("\nWho do you want to delete?\n");
int index = SearchContactsByName(contacts);
if (index < 0)
{
printf("\nThe contacts you just searched doesn't exist in your contacts.\n\n");
return;
}
PeopleInfo* peopleInfo = contacts->peopleInfo;
for (int i = index; i < contacts->peopleNums - 1; i++)
{
*(peopleInfo + i) = *(peopleInfo + i + 1);
}
contacts->peopleNums--;
printf("\nDELETE SUCCEED!\n\n");
}
static int CmpByAge(PeopleInfo* p1, PeopleInfo* p2)
{
return p1->age - p2->age;
}
static int CmpByName(PeopleInfo* p1, PeopleInfo* p2)
{
return strcmp(p1->name, p2->name);
}
static void SortPeopleInfo(Contacts* contacts, int (*pfCmp)(PeopleInfo*, PeopleInfo*))
{
PeopleInfo* peopleInfo = contacts->peopleInfo;
int size = contacts->peopleNums;
int sortedBorder = size - 1;
int lastExchange = 0;
for (int i = 0; i < size - 1; i++)
{
bool flg = true;
for (int j = 0; j < sortedBorder; j++)
{
if (pfCmp(peopleInfo + j, peopleInfo + j + 1) > 0)
{
flg = false;
PeopleInfo tmp = *(peopleInfo + j);
*(peopleInfo + j) = *(peopleInfo + j + 1);
*(peopleInfo + j + 1) = tmp;
lastExchange = j;
}
}
if (flg)
{
break;
}
sortedBorder = lastExchange;
}
}
void SortContacts(Contacts* contacts)
{
printf("Sorting by what?Please Choose:\n");
printf("********** 1. the age.\n");
printf("********** 2. the name.\n\n");
short input;
scanf("%hd", &input);
switch (input)
{
case 1:
printf("Sorting by age...\n\n");
SortPeopleInfo(contacts, CmpByAge);
break;
case 2:
printf("Sorting by name...\n\n");
SortPeopleInfo(contacts, CmpByName);
break;
default:
printf("\nWRONG CHOICE.\n");
break;
}
printf("The contacts information after sorting:\n\n");
ShowAllContacts(contacts);
}
4. 实现时该注意的地方
-
核心设计
-
初始化
-
realloc扩容通讯录
-
排序的设计
-
删除全部信息
-
释放动态内存