摘要:通訊錄主要由個功能增加聯(lián)系人刪除聯(lián)系人修改聯(lián)系人查找聯(lián)系人按名稱子排序。輸入,退出通訊錄。代碼實現(xiàn)打印菜單創(chuàng)建一個通訊錄初始化通訊錄請選擇退出通訊錄。
通過前面學習我們可以實現(xiàn)通訊錄小程序的代碼,首先,我們需要創(chuàng)建一個通訊錄,通訊錄中存放1000個人的信息,信息包括:名字,性別,年齡,電話,住址。通訊錄主要由5個功能:增加聯(lián)系人、刪除聯(lián)系人、修改聯(lián)系人、查找聯(lián)系人、按名稱子排序。下面我們來看實現(xiàn)過程。
首先我們將完整的代碼分為3個部分——contact.h(頭文件)、contact.c(函數(shù)部分)、test.c(主函數(shù)實現(xiàn)部分)。我們會創(chuàng)建一個大的框架,將菜單放入其中,菜單有7個選項:1.add 2.del 3.search 4.modify 5.show 6.sort 0.exit
輸入“1”,添加聯(lián)系人信息,輸入“2”,刪除指定聯(lián)系人信息,輸入“3”,查找指定聯(lián)系人信息(按姓名查找并打?。斎搿?”,修改指定聯(lián)系人信息(按姓名查找),輸入“5”,打印當前的通訊錄所有聯(lián)系人,輸入“6”,將通訊錄所有聯(lián)系人按姓名排序。輸入“0”,退出通訊錄。
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");}enum Option{ EXIT, ADD, DEL, SEARCH, MODIFY, SHOW, SORT};int main(){ int input=0; //創(chuàng)建一個通訊錄 struct Contact con; //初始化通訊錄 InitContact(&con); do { menu(); printf("請選擇:>"); 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: SortContactByName(&con); break; case EXIT: printf("退出通訊錄。/n"); break; default: printf("選擇錯誤!/n"); break; } } while (input); return 0;}
我們利用枚舉類型將EXIT,ADD,DEL,SEARCH,MODIFY,SHOW,SORT放入其中,因為枚舉類型中的成員屬于常量所以具有常量的屬性,我們可以利用此屬性運用到switch上,這樣就提高了代碼的可讀性。利用do while循環(huán),我們先打印menu()函數(shù),再利用input變量,只要輸入非0,都會打印菜單,只是效果不同。
//描述人的信息#define NAME_MAX 20#define SEX_MAX 5#define TELE_MAX 12#define ADDR_MAX 30#define MAX 1000struct PeoInfo{ char name[NAME_MAX]; int age; char sex[SEX_MAX]; char tele[TELE_MAX]; char addr[ADDR_MAX];};//通訊錄struct Contact{ struct PeoInfo data[MAX];//1000個人的信息存放進data數(shù)組中 int sz ;//記錄當前存放進通訊錄中的有效信息的個數(shù)};
定義一個通訊錄需要兩個結(jié)構體,struct PeoInfo結(jié)構體是描述一個人的信息,struct Contact結(jié)構體是通訊錄本身,我們將struct PeoInfo中的個人信息存放在struct Contact結(jié)構體中以實現(xiàn)聯(lián)系,也就是struct Contact的成員data[1000]是struct PeoInfo結(jié)構體類型,data[1000]是一個結(jié)構體類型的數(shù)組,里面有name[20],age,sex[5],tele[12],addr[30]。
void InitContact(struct Contact* pc){ pc->sz = 0;//默認沒有信息 //memset(pc->data, 0, MAX * sizeof(struct PeoInfo)); memset(pc->data, 0, sizeof(pc->data));}
當我們定義一個通訊錄結(jié)構體時,數(shù)值都是隨機值,因此我們需要初始化,將通訊錄所有的信息數(shù)據(jù)都變成“0”,這里使用了memset()函數(shù),我們在內(nèi)存函數(shù)博客中介紹了這個函數(shù),不在細說。具體實現(xiàn)原理可以看前面的博客內(nèi)存函數(shù)(C語言)
void AddContact(struct Contact* pc){ if (pc->sz == MAX) { printf("通訊錄已滿!/n"); } else { printf("請輸入名字:>"); scanf("%s", pc->data[pc->sz].name); printf("請輸入年齡:>"); scanf("%d", &(pc->data[pc->sz].age)); printf("請輸入性別:>"); scanf("%s", pc->data[pc->sz].sex); printf("請輸入電話:>"); scanf("%s", pc->data[pc->sz].tele); printf("請輸入地址:>"); scanf("%s", pc->data[pc->sz].addr ); //提示添加成功 printf("添加成功/n"); pc->sz++; }}
AddContact()函數(shù),首先先進行判斷,sz(記錄當前存放進通訊錄中的有效信息的個數(shù))是否等于MAX(1000),如果有,則打印通訊錄已滿,如果沒有則按要求輸入信息,并提示添加成功,sz++。
void ShowContact(struct Contact* pc){ int i = 0; printf("%15s/t%5s/t%8s/t%15s/t%30s/n/n", "name", "age", "sex", "tele", "addr"); for (i = 0; i < pc->sz; i++) { //打印每一個數(shù)據(jù) printf("%15s/t%5d/t%8s/t%15s/t%30s/n", pc->data[i].name, pc->data[i].age, pc->data[i].sex, pc->data[i].tele, pc->data[i].addr); }}
在ShowContact()函數(shù)中,我們先打印標題"name", “age”, “sex”, “tele”, “addr”,然后利用for循環(huán)將信息一一對應標題都打印下來。
int FindContactByName(const struct Contact* pc, const char *name){ int i = 0; for (i = 0; i < pc->sz; i++) { if (strcmp(pc->data[i].name, name) == 0) { return i; } } //找不到 return -1;}
FindContactByName()函數(shù)的基本實現(xiàn)是通過strcmp()函數(shù)實現(xiàn)的,利用for循環(huán),找到查找的名字于通訊錄名字相等的此時i的值,并返回i的值,此時i的值正是data數(shù)組的下標,方便后續(xù)操作,關于strcmp()函數(shù)實現(xiàn)原理可以看以前博客字符與字符串函數(shù)(C語言)。
void DelContact(struct Contact* pc){ if (pc->sz == 0) { printf("通訊錄為空,無法刪除/n"); return; } char name[NAME_MAX] = { 0 }; printf("請輸入要刪除人的名字:>"); scanf("%s", name); //查找 int pos = FindContactByName(pc, name); if (pos == -1) { printf("指定的聯(lián)系人不存在/n"); } else { //刪除 int j = 0; for (j = pos; j < pc->sz-1; j++) { pc->data[j] = pc->data[j + 1]; } pc->sz--; //提示 printf("刪除成功/n"); }}
DelContact()函數(shù)和AddContact()函數(shù)類似,但是比添加聯(lián)系人要復雜,刪除聯(lián)系人先再找到指定的聯(lián)系人,在進行操作,因此,DelContact()函數(shù)中運用了查找通訊錄函數(shù),利用名字進行比較找出指定的聯(lián)系人,在進行刪除時,并不是直接刪除,而是利用后一個信息將前一個信息的覆蓋,如此達到刪除聯(lián)系人的信息。
void SearchContact(const struct Contact* pc){ char name[NAME_MAX] = { 0 }; printf("輸入要查找人的名字:>"); scanf("%s", name); int pos = FindContactByName(pc, name); if (-1 == pos) { printf("查無此人/n"); } else { printf("%15s/t%5s/t%8s/t%15s/t%30s/n/n", "name", "age", "sex", "tele", "addr"); printf("%15s/t%5d/t%8s/t%15s/t%30s/n", pc->data[pos].name, pc->data[pos].age, pc->data[pos].sex, pc->data[pos].tele, pc->data[pos].addr); }}
SearchContact()函數(shù)是在FindContactByName()函數(shù)的基礎之上增加了打印的功能,如果沒有查找到指定的聯(lián)系人打印“查無此人”,否則打印出該聯(lián)系人的所有信息。
void ModifyContact(struct Contact* pc){ char name[NAME_MAX] = { 0 }; printf("輸入要修改人的名字:>"); scanf("%s", name); int pos = FindContactByName(pc, name); if (-1 == pos) { printf("要修改的人不存在/n"); } else { printf("請輸入新的名字:>"); scanf("%s", pc->data[pos].name); printf("請輸入新的年齡:>"); scanf("%d", &(pc->data[pos].age)); printf("請輸入新的性別:>"); scanf("%s", pc->data[pos].sex); printf("請輸入新的電話:>"); scanf("%s", pc->data[pos].tele); printf("請輸入新的地址:>"); scanf("%s", pc->data[pos].addr); }}
ModifyContact()函數(shù)是利用FindContactByName()函數(shù)先將想要修改的聯(lián)系人找到,然后輸入新的所有信息來覆蓋原來的信息。
int cmp_name(const void* e1, const void* e2){ return strcmp(((struct Contact*)e1)->data->name , ((struct Contact*)e2)->data->name);}void SortContactByName(struct Contact* pc){ qsort(pc->data, pc->sz, sizeof(pc->data[0]), cmp_name); printf("排序成功/n");}
排序運用到了qsort()函數(shù),這個函數(shù)可以排序任意類型的數(shù)據(jù),因此結(jié)構體也可以。但是需要引用到頭文件#include
qsort()函數(shù):
形式:void qsort( void *base, size_t num, size_t width, int (__cdecl *compare )(const void *elem1, const void *elem2 ) )
解釋:qsort函數(shù)實現(xiàn)了一種快速排序算法,用于對num元素數(shù)組進行排序,每個元素的寬度為字節(jié)。參數(shù)base是指向要排序的數(shù)組的基的指針。qsort用已排序的元素覆蓋此數(shù)組。參數(shù)compare是指向用戶提供的例程的指針,該例程比較兩個數(shù)組元素并返回指定其關系的值。
也就是說,*base是一個指針,num是要排序的個數(shù),width是排序元素的大小,int (__cdecl *compare )(const void *elem1, const void *elem2 ) 是一個函數(shù),這個函數(shù)就是用來判斷怎樣比較的。以寫的代碼為例,pc是指針指向的是struct Contact con結(jié)構體,pc->sz是記錄當前存放進通訊錄中的有效信息的個數(shù),也就對應了打印的個數(shù),sizeof(pc->data[0])是個人信息的結(jié)構體的大小,cmp_name()函數(shù)是按名字來進行排序。
#include #include #include #define NAME_MAX 20#define SEX_MAX 5#define TELE_MAX 12#define ADDR_MAX 30#define MAX 1000//描述人的信息struct PeoInfo{ char name[NAME_MAX]; int age; char sex[SEX_MAX]; char tele[TELE_MAX]; char addr[ADDR_MAX];};//通訊錄struct Contact{ struct PeoInfo data[MAX];//1000個人的信息存放進data數(shù)組中 int sz ;//記錄當前存放進通訊錄中的有效信息的個數(shù)};//初始化通訊錄void InitContact(struct Contact* pc);//增加聯(lián)系人void AddContact(struct Contact* pc);//顯示通訊錄void ShowContact(struct Contact* pc);//刪除聯(lián)系人void DelContact(struct Contact* pc);//查找指定聯(lián)系人void SearchContact(const struct Contact* pc);//修改指定聯(lián)系人void ModifyContact(struct Contact* pc);//按姓名排序通訊錄void SortContactByName(struct Contact* pc);
用#define定義的常量能夠方便代碼的修改,增加了代碼的維護性。
#include"contact.h"void InitContact(struct Contact* pc){ pc->sz = 0;//默認沒有信息 //memset(pc->data, 0, MAX * sizeof(struct PeoInfo)); memset(pc->data, 0, sizeof(pc->data));}void AddContact(struct Contact* pc){ if (pc->sz == MAX) { printf("通訊錄已滿!/n"); } else { printf("請輸入名字:>"); scanf("%s", pc->data[pc->sz].name); printf("請輸入年齡:>"); scanf("%d", &(pc->data[pc->sz].age)); printf("請輸入性別:>"); scanf("%s", pc->data[pc->sz].sex); printf("請輸入電話:>"); scanf("%s", pc->data[pc->sz].tele); printf("請輸入地址:>"); scanf("%s", pc->data[pc->sz].addr ); //提示添加成功 printf("添加成功/n"); pc->sz++; }}void ShowContact(struct Contact* pc){ int i = 0; printf("%15s/t%5s/t%8s/t%15s/t%30s/n/n", "name", "age", "sex", "tele", "addr"); for (i = 0; i < pc->sz; i++) { //打印每一個數(shù)據(jù) printf("%15s/t%5d/t%8s/t%15s/t%30s/n", pc->data[i].name, pc->data[i].age, pc->data[i].sex, pc->data[i].tele, pc->data[i].addr); }}int FindContactByName(const struct Contact* pc, const char *name){ int i = 0; for (i = 0; i < pc->sz; i++) { if
文章版權歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/121134.html
摘要:還有書,入門的書我買了好幾本,到最后真正看的只有一本,就是譚浩強的那本。當然也不排除特別差的教程,我當初的入門教程是小甲魚的,叫做帶你學帶你飛,書是譚浩強的語言程序設計第四版。 首先,本人也是一個菜鳥,目前依然還在學習,當初在我開始自學C語言的時候,走過了好多彎路,如果你看到這篇文章,希望你不要走我走過的彎路,這也是我寫這篇文章的目的,我也不想像老頭子一樣叨叨叨,哪些要做,哪些不要做,...
摘要:最近微信小程序異常火爆,很多人在學習,下面帶著大家搭建下微信小程序的調(diào)試環(huán)境,并調(diào)試入門練手項目通訊錄和基礎即可微信推薦使用的語言,去菜鳥教程簡單學習下,,,即可,方便大家學習。 一、前言(坑爹的玩意) 項目源碼:https://github.com/saucxs/wx_... 微信小程序自從2017年,被各種看好,不過一段時間過去了還是反響平平,下半年隨著各項功能的開放,很多企業(yè)...
閱讀 4632·2021-09-26 09:55
閱讀 1373·2019-12-27 12:16
閱讀 891·2019-08-30 15:56
閱讀 1909·2019-08-30 14:05
閱讀 997·2019-08-30 13:05
閱讀 1271·2019-08-30 10:59
閱讀 1449·2019-08-26 16:19
閱讀 1890·2019-08-26 13:47