通訊錄是一個(gè)可以很好鍛煉我們對(duì)結(jié)構(gòu)體的使用,加深對(duì)結(jié)構(gòu)體的理解,在為以后學(xué)習(xí)數(shù)據(jù)結(jié)構(gòu)打下結(jié)實(shí)的基礎(chǔ)
這里我們想設(shè)計(jì)一個(gè)有添加聯(lián)系人,刪除聯(lián)系人,查找聯(lián)系人,修改聯(lián)系人,展示聯(lián)系人,排序
這幾種功能的通訊錄
注意:我們按照三個(gè)區(qū)域劃分
上圖所示進(jìn)行區(qū)域劃分
- con.c用來放實(shí)現(xiàn)功能的函數(shù)
- con.h用來放頭文件的聲明
- test.c用來放整體框架
整體框架:
使用do...while
循環(huán)創(chuàng)建整體框架
整體框架在
test.c
中,這部分我們用來測試代碼
int main()
{
int input = 0;
InitContact(&Con);
do
{
menu();
printf("請(qǐng)輸入你的選項(xiàng)\n");
scanf("%d", &input);
switch (input)
{
case Add:
break;
case Del:
break;
case Search:
break;
case Modify:
break;
case Show:
break;
case Sort:
break;
case Exit:
printf("你已成功退出\n");
break;
default:
printf("輸入錯(cuò)誤,請(qǐng)重新輸入\n");
break;
}
} while (input);
return 0;
}
-
注意:
-
我在使用case語句時(shí)沒有用數(shù)字1,2,3…
而是使用了枚舉常量,因?yàn)槊杜e常量會(huì)更方便程序員查看與操作要與菜單的數(shù)字相匹配,不然就會(huì)弄巧成拙
enum option
{
Exit,
Add,
Del,
Search,
Modify,
Show,
Sort,
};
菜單:
菜單的設(shè)計(jì)隨心所欲,但要與枚舉相匹配!
void menu()
{
printf("**************************\n");
printf("*** 1.Add 2.Del **\n");
printf("*** 3.Search 4.Modify **\n");
printf("*** 5.Show 6.Sort **\n");
printf("*** 0.Exit **\n");
printf("**************************\n");
printf("**************************\n");
}
創(chuàng)建通訊錄:
此部分我們?cè)?code>Contact.h中創(chuàng)建,在另外兩個(gè)里
include
就可以
創(chuàng)建通訊錄之前要先創(chuàng)建一個(gè)聯(lián)系人的結(jié)構(gòu)體:
假設(shè)我們的結(jié)構(gòu)體包含了一個(gè)人的姓名,年齡,性別,電話,住址
那么久可以很好的進(jìn)行創(chuàng)建:
typedef struct PeoInfo
{
char name[NAME_MAX];
int age;
char sex[SEX_MAX];
char tele[TELE_MAX];
char addr[ADDR_MAX];
}PeoInfo;
其中的常量用define
按需求進(jìn)行定義,避免牽一發(fā)而動(dòng)全身的情況
#define NAME_MAX 20
#define SEX_MAX 5
#define TELE_MAX 12
#define ADDR_MAX 30
因?yàn)橐獎(jiǎng)討B(tài)通訊錄
故設(shè)計(jì)通訊錄時(shí)不能使用PeoInfo
創(chuàng)建數(shù)組的方式進(jìn)行
可以創(chuàng)建結(jié)構(gòu)體指針,指向動(dòng)態(tài)內(nèi)存分配的空間
typedef struct Contact
{
PeoInfo* Data;
int sz;
int capacity;
}Contact;
最后在test.c
文件中創(chuàng)建通訊錄 Contact Con;
初始化:
在
con.c
中進(jìn)行設(shè)計(jì),不要忘記在test.c
中調(diào)用,在con.h
中聲明
實(shí)現(xiàn)功能皆是如此設(shè)計(jì),將不在贅述
void InitContact(Contact* pc)
{
assert(pc);
pc->sz = 0;
pc->capacity = START;
PeoInfo* p = (PeoInfo*)malloc(sizeof(PeoInfo) * START);
//start為初始化大小,define定義為3
if (p != NULL)
{
pc->Data = p;
}
else
{
perror("InitContact->malloc");
}
}
實(shí)現(xiàn)功能:
添加聯(lián)系人:
void AddContact(Contact* pc)
{
assert(pc);
if (pc->sz == pc->capacity)
{
PeoInfo* str = (PeoInfo*)realloc
(pc->Data, sizeof(PeoInfo) *
(pc->capacity + START_ADD));
//START_ADD為define定義,為一次擴(kuò)容數(shù)量
if (str != NULL)
{
pc->Data = str;
pc->capacity = pc->capacity + START_ADD;
printf("增容成功\n");
}
else
{
perror("AddContact->realloc");
return;
}
}
printf("輸入名字\n");
scanf("%s", pc->Data[pc->sz].name);
printf("輸入年齡\n");
scanf("%d", &pc->Data[pc->sz].age);
printf("輸入性別\n");
scanf("%s", &pc->Data[pc->sz].sex);
printf("輸入電話\n");
scanf("%s", &pc->Data[pc->sz].tele);
printf("輸入住址\n");
scanf("%s", &pc->Data[pc->sz].addr);
printf("輸入成功\n");
pc->sz++;
}
刪除聯(lián)系人:
void DelContact(Contact* pc)
{
if (pc->sz == 0)
{
printf("通訊錄為空,無需刪除\n");
return;
}
char name[NAME_MAX];
printf("輸入你要?jiǎng)h除人的姓名\n");
scanf("%s", name);
int ret = find(pc, name);
//我們這里使用了find函數(shù)
if (ret == -1)
{
printf("查無此人\n");
return;
}
for (int i = ret; i < pc->sz-1; i++)
{
pc->Data[i] = pc->Data[i + 1];
}
pc->sz--;
}
我們?cè)谳斎氩檎倚彰笠M(jìn)行查找,因此我們?cè)O(shè)計(jì)了一個(gè)find
函數(shù),方便別的函數(shù)的使用
find()的定義:
int find(Contact* pc, char name[])
{
for (int i = 0; i < pc->sz; i++)
{
if (strcmp(name, pc->Data[i].name) == 0)
{
return i;
}
}
return -1;
}
查找聯(lián)系人:
void SearchContact(Contact* pc)
{
if (pc->sz == 0)
{
printf("通訊錄為空\n");
return;
}
char name[NAME_MAX];
printf("輸入你要查找人的姓名\n");
scanf("%s", name);
int ret = find(pc, name);
if (ret == -1)
{
printf("查無此人\n");
return;
}
printf(" % -20s % -5s % -5s % -20s % -20s\n", "姓名", "年齡", "性別", "電話", "住址");
printf(" % -20s % -5d % -5s % -20s % -20s\n",
pc->Data[ret].name, pc->Data[ret].age, pc->Data[ret].sex, pc->Data[ret].tele, pc->Data[ret].addr);
}
修改聯(lián)系人:
void ModifyContact(Contact* pc)
{
if (pc->sz == 0)
{
printf("通訊錄為空\n");
return;
}
char name[NAME_MAX];
printf("輸入你要修改人的姓名\n");
scanf("%s", name);
int ret = find(pc, name);
if (ret == -1)
{
printf("查無此人\n");
return;
}
printf("輸入名字\n");
scanf("%s", pc->Data[ret].name);
printf("輸入年齡\n");
scanf("%d", &pc->Data[ret].age);
printf("輸入性別\n");
scanf("%s", &pc->Data[ret].sex);
printf("輸入電話\n");
scanf("%s", &pc->Data[ret].tele);
printf("輸入住址\n");
scanf("%s", &pc->Data[ret].addr);
printf("輸入成功\n");
}
展示聯(lián)系人:
void ShowContact(Contact* pc)
{
if (pc->sz == 0)
{
printf("通訊錄為空,無需打印\n");
return;
}
printf(" % -20s % -5s % -5s % -20s % -20s\n", "姓名", "年齡", "性別", "電話", "住址");
for (int i = 0; i < pc->sz; i++)
{
printf(" % -20s % -5d % -5s % -20s % -20s\n",
pc->Data[i].name, pc->Data[i].age, pc->Data[i].sex, pc->Data[i].tele, pc->Data[i].addr);
}
}
排序:
排序可以按照名字排,或是年齡,亦或是性別等等
這里我們只進(jìn)行名字的排序,使用方法大同小異(快排)
int cmp_name(void* e1,void* e2)
{
return strcmp(((PeoInfo*)e1)->name, ((PeoInfo*)e2)->name);
}
void SortContact(Contact* pc)
{
qsort(pc->Data, pc->sz, sizeof(PeoInfo), cmp_name);
}
free空間:
最后一步就是釋放空間有始有終
void DestoryContact(Contact* pc)
{
free(pc->Data);
pc->Data=NULL;
pc->sz=0;
pc->capacity=0;
}
源代碼:
con.c
#define _CRT_SECURE_NO_WARNINGS 1
#include "contact.h"
int find(Contact* pc, char name[])
{
for (int i = 0; i < pc->sz; i++)
{
if (strcmp(name, pc->Data[i].name) == 0)
{
return i;
}
}
return -1;
}
//void InitContact(Contact* pc)
//{
// assert(pc);
// pc->sz = 0;
// memset(pc->Data, 0, sizeof(pc->Data));
//}
void InitContact(Contact* pc)
{
assert(pc);
pc->sz = 0;
pc->capacity = START;
PeoInfo* p = (PeoInfo*)malloc(sizeof(PeoInfo) * START);
if (p != NULL)
{
pc->Data = p;
}
else
{
perror("InitContact->malloc");
}
}
void DestoryContact(Contact* pc)
{
free(pc);
}
void AddContact(Contact* pc)
{
assert(pc);
if (pc->sz == pc->capacity)
{
PeoInfo* str = (PeoInfo*)realloc(pc->Data, sizeof(PeoInfo) * (pc->capacity + START_ADD));
if (str != NULL)
{
pc->Data = str;
pc->capacity = pc->capacity + 2;
printf("增容成功\n");
}
else
{
perror("AddContact->realloc");
return;
}
}
printf("輸入名字\n");
scanf("%s", pc->Data[pc->sz].name);
printf("輸入年齡\n");
scanf("%d", &pc->Data[pc->sz].age);
printf("輸入性別\n");
scanf("%s", &pc->Data[pc->sz].sex);
printf("輸入電話\n");
scanf("%s", &pc->Data[pc->sz].tele);
printf("輸入住址\n");
scanf("%s", &pc->Data[pc->sz].addr);
printf("輸入成功\n");
pc->sz++;
}
void ShowContact(Contact* pc)
{
if (pc->sz == 0)
{
printf("通訊錄為空,無需打印\n");
return;
}
printf(" % -20s % -5s % -5s % -20s % -20s\n", "姓名", "年齡", "性別", "電話", "住址");
for (int i = 0; i < pc->sz; i++)
{
printf(" % -20s % -5d % -5s % -20s % -20s\n",
pc->Data[i].name, pc->Data[i].age, pc->Data[i].sex, pc->Data[i].tele, pc->Data[i].addr);
}
}
void DelContact(Contact* pc)
{
if (pc->sz == 0)
{
printf("通訊錄為空,無需刪除\n");
return;
}
char name[NAME_MAX];
printf("輸入你要?jiǎng)h除人的姓名\n");
scanf("%s", name);
int ret = find(pc, name);
if (ret == -1)
{
printf("查無此人\n");
return;
}
for (int i = ret; i < pc->sz-1; i++)
{
pc->Data[i] = pc->Data[i + 1];
}
pc->sz--;
}
void SearchContact(Contact* pc)
{
if (pc->sz == 0)
{
printf("通訊錄為空\n");
return;
}
char name[NAME_MAX];
printf("輸入你要查找人的姓名\n");
scanf("%s", name);
int ret = find(pc, name);
if (ret == -1)
{
printf("查無此人\n");
return;
}
printf(" % -20s % -5s % -5s % -20s % -20s\n", "姓名", "年齡", "性別", "電話", "住址");
printf(" % -20s % -5d % -5s % -20s % -20s\n",
pc->Data[ret].name, pc->Data[ret].age, pc->Data[ret].sex, pc->Data[ret].tele, pc->Data[ret].addr);
}
void ModifyContact(Contact* pc)
{
if (pc->sz == 0)
{
printf("通訊錄為空\n");
return;
}
char name[NAME_MAX];
printf("輸入你要修改人的姓名\n");
scanf("%s", name);
int ret = find(pc, name);
if (ret == -1)
{
printf("查無此人\n");
return;
}
printf("輸入名字\n");
scanf("%s", pc->Data[ret].name);
printf("輸入年齡\n");
scanf("%d", &pc->Data[ret].age);
printf("輸入性別\n");
scanf("%s", &pc->Data[ret].sex);
printf("輸入電話\n");
scanf("%s", &pc->Data[ret].tele);
printf("輸入住址\n");
scanf("%s", &pc->Data[ret].addr);
printf("輸入成功\n");
}
int cmp_name(void* e1,void* e2)
{
return strcmp(((PeoInfo*)e1)->name, ((PeoInfo*)e2)->name);
}
void SortContact(Contact* pc)
{
qsort(pc->Data, pc->sz, sizeof(PeoInfo), cmp_name);
}
con.h
#pragma once
#include<stdio.h>
#include<string.h>
#include<assert.h>
#include<stdlib.h>
#define NAME_MAX 20
#define SEX_MAX 5
#define TELE_MAX 12
#define ADDR_MAX 30
#define START 3
#define START_ADD 2
typedef struct PeoInfo
{
char name[NAME_MAX];
int age;
char sex[SEX_MAX];
char tele[TELE_MAX];
char addr[ADDR_MAX];
}PeoInfo;
typedef struct Contact
{
PeoInfo* Data;
int sz;
int capacity;
}Contact;
//init
void InitContact(Contact* pc);
//add
void AddContact(Contact* pc);
//show
void ShowContact(Contact* pc);
//del
void DelContact(Contact* pc);
//search
void SearchContact(Contact* pc);
//modify
void ModifyContact(Contact* pc);
//sort
void SortContact(Contact* pc);
//destory
void DestoryContact(Contact* pc);
test.c文章來源:http://www.zghlxwxcb.cn/news/detail-721049.html
#define _CRT_SECURE_NO_WARNINGS 1
#include "contact.h"
enum option
{
Exit,
Add,
Del,
Search,
Modify,
Show,
Sort,
};
void menu()
{
printf("**************************\n");
printf("*** 1.Add 2.Del **\n");
printf("*** 3.Search 4.Modify **\n");
printf("*** 5.Show 6.Sort **\n");
printf("*** 0.Exit **\n");
printf("**************************\n");
printf("**************************\n");
}
int main()
{
int input = 0;
Contact Con;
InitContact(&Con);
do
{
menu();
printf("請(qǐng)輸入你的選項(xiàng)\n");
scanf("%d", &input);
switch (input)
{
case Add:
AddContact(&Con);
break;
case Del:
DelContact(&Con);
break;
case Search:
SearchContact(&Con);
break;
case Modify:
ModifyContact(&Con);
break;
case Show:
ShowContact(&Con);
break;
case Sort:
SortContact(&Con);
break;
case Exit:
DestoryContact(&Con);
printf("你已成功退出\n");
break;
default:
printf("輸入錯(cuò)誤,請(qǐng)重新輸入\n");
break;
}
} while (input);
return 0;
}
歡迎糾錯(cuò)與討論文章來源地址http://www.zghlxwxcb.cn/news/detail-721049.html
到了這里,關(guān)于【C語言】動(dòng)態(tài)通訊錄(超詳細(xì))的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!