摘要:二靜態通訊錄接口函數實現文件名功能通訊錄函數接口的實現宏定義,頭文件,接口函數的聲明函數接口測試靜態通訊錄的基本結構通訊錄是一個結構體。
前言:之前,博主已經寫過兩個有意思的小項目:三子棋和掃雷,接下來,博主繼續更新一個小項目-通訊錄,包括3種版本,靜態版,動態版,文件保存版。接下來,我們先講解如何實現靜態版。
目錄
靜態通訊錄:使用的是定長數組,即數組的長度不能發生改變。我們可以設置通訊錄可以記錄的成員個數為1000個。
文件名 | 功能 |
Contact.c | 通訊錄函數接口的實現 |
Contact.h | 宏定義,頭文件,接口函數的聲明 |
test.c | 函數接口測試 |
通訊錄是一個結構體。
包含:1.通訊錄成員數組,每一個通訊錄成員又是一個結構體,包括:地址,姓名,年齡,性別,地址,電話。
? ? ? ? ? 2.標志通訊錄成員個數的變量。
注意:為了方便后序更改通訊錄的各種大小,推薦使用宏定義
//注意宏定義后面不要跟分號!!!!不然會有問題#define NAME_MAX 30 //名字最大長度#define SEX_MAX 5 //性別最大長度#define TELE_MAX 12 //電話最大長度#define ADDR_MAX 30 //地址最大長度#define MAX 1000 //通訊錄數組的成員總數typedef struct PeoInfo{ char name[NAME_MAX]; int age; char sex[SEX_MAX]; char addr[ADDR_MAX]; char tele[TELE_MAX];}PeoInfo;struct Contact //通訊錄{ PeoInfo data[MAX]; //結構體成員數組 int size; //標志通訊錄中所含成員個數, 控制數組下標};
enum Option{ EXIT, ADD, DEL, SEARCH, MODIFY, SHOW, DESTORY,};void menu(){ printf("******************************/n"); printf("**** 1. add 2. del *****/n"); printf("**** 3. search 4. modify****/n"); printf("**** 5. show 6. Destory ***/n"); printf("**** 0. exit **/n"); printf("******************************/n");}int main(){ int input = 0; struct Contact con; //創建通訊錄,內含MAX個結構體成員 InitContact(&con); //初始化通訊錄 do { menu(); printf("請選擇->/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 DESTORY: DesContact(&con); break; case EXIT: printf("退出成功!歡迎再次使用!/n"); break; default: printf("選擇錯誤,請重新選擇/n"); break; } } while (input); return 0;}
使用memset初始化通訊錄成員數組
寫法1:每個成員的大小*成員個數?
void InitContact(struct Contact* ps){ assert(ps); //最初沒有數據 memset(ps->data, 0, sizeof(PeoInfo) * MAX); //通訊錄成員數組初始化為0 ps->size = 0;//默認成員為0}
寫法2:數組多帶帶放在sizeof內部->計算的是整個數組的大小?
//寫法2void InitContact(struct Contact* ps){ memset(ps->data, 0, sizeof(ps->data)); //ps->data拿到了通訊錄中PenInfo數組的數組名//數組名多帶帶放在sizeof內部,計算的是整個數組的大小 ps->size = 0;}
為了更直觀,我們可以把標題也進行打印。通過遍歷通訊錄成員數組,即可把成員打印出來。
//這是右對齊 如果想要左對齊-> -%30d前面加符號 在%前面數字加負號void ShowContact(struct Contact* ps){ int i = 0; //打印標題 printf("%15s/t%5s/t%8s/t%15s/t%30s/t/n/n", "name", "age", "sex", "tele", "addr"); //打印數組中每個結構體成員的內容 for (i = 0; i < ps->size; i++) { printf("%15s/t%5d/t%8s/t%15s/t%30s/n", ps->data[i].name, ps->data[i].age, ps->data[i].sex, ps->data[i].tele, ps->data[i].addr); }}
寫法1:直接對通訊錄成員數組進行操作
void ADDContact(struct Contact* ps){ //先判斷通訊錄是否滿了 if (ps->size == MAX) { printf("通訊錄已滿/n"); } else { printf("請輸入名字:"); scanf("%s", ps->data[ps->size].name); //數組名不用& printf("請輸入年齡: "); scanf("%d", &(ps->data[ps->size].age)); printf("請輸入地址:"); scanf("%s", ps->data[ps->size].addr); printf("請輸入號碼:"); scanf("%s", ps->data[ps->size].tele); printf("請輸入性別:"); scanf("%s", ps->data[ps->size].sex); printf("添加成功/n"); ps->size++; //添加了一個成員,size++ }}
?寫法2:先創建一個臨時結構體成員,然后賦值后,賦給通訊錄結構體數組中ps->size位置
//增加成員的寫法2:void ADDContact(struct Contact* ps){ PeoInfo tmp = { 0 }; //先判斷通訊錄是否滿了 if (ps->size == MAX) { printf("通訊錄已滿/n"); } else { printf("請輸入名字:"); scanf("%s", tmp.name); //數組名不用& printf("請輸入年齡: "); scanf("%d", &(tmp.age)); printf("請輸入地址:"); scanf("%s", tmp.addr); printf("請輸入號碼:"); scanf("%s", tmp.tele); printf("請輸入性別:"); scanf("%s", tmp.sex); ps->data[ps->size] = tmp; printf("添加成功/n"); ps->size++; }}
因為size 標志的是通訊錄中的成員個數,所以只要判斷size是否為0即可知道通訊錄是否為空
//如果為空,判斷成立,返回1bool EmptyContact(struct Contact* ps){ return ps->size == 0;}
因為后續刪除指定聯系人,更改指定聯系人的信息都需要進行查找,所以可以把查找函數多帶帶封裝
找到了,返回對應的下標,找不到返回-1
因為不作修改,所以可以加上const修飾
方法:遍歷結構體成員數組進行查找
int FindContactByName(const struct Contact* ps,const char*name ){ //遍歷查找 int i = 0; for(i = 0;i< ps->size;i++) { if( strcmp(name,ps->data[i].name) == 0) { //返回下標 return i; } } return -1;}
注意:刪除聯系人->從該位置開始后面的數據往前覆蓋
如通訊錄為空,則不刪除,直接返回.
void DelContact(struct Contact* ps){ if (EmptyContact(ps)) { printf("通訊錄為空,無法刪除/n"); return ; } char name[NAME_MAX] = { 0 }; //用來存儲要刪除的指定聯系人的名字 printf("請輸入要刪除人得名字:>"); scanf("%s",name); //查找 int pos = FindContactByName(ps, name); if (pos == -1) { printf("指定的聯系人不存在/n"); } else { //刪除操作 //從pos位置開始,后面的往前覆蓋 int i = 0; for (i = pos; i < ps->size - 1; i++) { ps->data[i] = ps->data[i + 1]; } //刪除了元素,size-- ps->size--; printf("刪除成功/n"); }}
方法:輸入要查找的聯系人名字,調用查找函數進行查找,若找到,返回對應下標,就把該下標對應的聯系人對應信息打印出來
void SearchContact(const struct Contact* ps){ char name[NAME_MAX] = {0}; printf("輸入要查找的聯系人:>"); scanf("%s",name); int pos =FindContactByName(ps,name); if(pos == -1) { printf("要查找的聯系人不存在/n"); } else { // 打印該聯系人對應的信息 //打印標題 printf("%15s/t%5s/t%8s/t%15s/t%30s/t/n/n", "name", "age", "sex", "tele", "addr"); printf("%15s/t%5d/t%8s/t%15s/t%30s/n", ps->data[pos].name, ps->data[pos].age, ps->data[pos].sex, ps->data[pos].tele, ps->data[pos].addr); } }}
方法:輸入要查找的聯系人名字,調用查找函數進行查找,找到了返回對應下標,然后修改對應數組下標的內容
void ModifyContact(struct Contact* ps){ char name[NAME_MAX] = { 0 }; printf("請輸入要修改人名字:>"); scanf("%s", name); int pos = FindContactByName(ps, name); if (-1 == pos) { printf("查無此人/n"); } else { printf("請輸入新名字:"); scanf("%s", ps->data[pos].name); //數組名不用& printf("請輸入新年齡: "); scanf("%d", &(ps->data[pos].age)); printf("請輸入新地址:"); scanf("%s", ps->data[pos].addr); printf("請輸入新號碼:"); scanf("%s", ps->data[pos].tele); printf("請輸入新性別:"); scanf("%s", ps->data[pos].sex); }}
相當于字符串比較->使用strcmp
這里可以使用兩種方法:冒泡排序或者qsort排序
關于qsort:qsort函數詳解
?比較的是通訊錄成員數組中的成員名字!!!
void SortContact(struct Contact* pcon){ int i, j; struct PeoInfo tmp; for(i = 0; i < pcon->sz - 1; i++) { for(j = 0; j < pcon->sz - 1 - i; j++) { if(0 < strcmp(pcon->data[j].name, pcon->data[j + 1].name)) { tmp = pcon->data[j]; pcon->data[j] = pcon->data[j + 1]; pcon->data[j + 1] = tmp; } } }}
void SortContactByName(struct Contact* ps){ qsort(ps->data, ps->size, sizeof(ps->data[0]), cmp_ContactByName);}int cmp_ContactByName(const void* e1, const void* e2){ return strcmp( ((struct PeoInfo*)e1)->name, ((struct PeoInfo*)e2)->name);}//注意// ((struct PeoInfo*)e1)->name 要括起來,// (struct PeoInfo*)e1->name 這樣寫是錯誤的
注意排序的是通訊錄里面的成員數組ps->data:每個元素的類型為struct PenInfo ( 結構體成員類型)要排序的個數為ps->size
size標志的是通訊錄成員個數
比較函數:比較的是成員的年齡
void SortContact(struct Contact* ps){ qsort(ps->data, ps->size, sizeof(ps->data[0]), cmp_ContactbyAge);}int cmp_ContactbyAge(const void* e1, const void* e2){ return ((struct PeoInfo*)e1)->age - ((struct PeoInfo*)e2)->age;}
清空通訊錄:相當于堆通訊錄重新初始化.
void ClearContact(Contact* pcon){ InitContact(pcon);}
成員有限:容易造成空間浪費/空間不夠的情況。
為了解決這個問題,下一篇文章,博主將會帶大家了解動態通訊錄.
很感謝你能看到這里,~如果感覺對你有幫助,歡迎給博主一個三連呀~
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/121541.html
摘要:那么我們首先來改造儲存空間也就是通訊錄結構體靜態版本人信息存放在數組中統計存放的人數動態版本統計存放的人數有效容量我們將原本的結構體數組改為一個結構體指針,以此來維護用以儲存個人信息的空間。 上一期我們編寫了一個C語言版本的簡易通訊錄,但是我們的之前的通訊錄是沒有記憶功能的,也就是說,一旦關...
摘要:之前的通訊錄在程序退出后內部的數據就會消失,再次打開程序后只能重新輸入數據,為此我們增加了一個保存功能來保存信息。 前言: 由于之前實現的通訊錄在存儲方面只能支持靜態的1000人的存儲量,但是如果聯系人較少,則會造成較大的內存浪費。而當聯系人一旦超過1000時,就不能再繼續存儲信息了。因...
??C語言通訊錄管理系統(簡易版)?? ?一、通訊錄?二、菜單實現和用戶交互?三、主函數????1.enum選項????2.switch判斷 ?四、定義聯系人和通訊錄????1.定義聯系人結構體????2.定義通訊錄結構體????3.定義結構體變量 ?五、通訊錄初始化?六、新增聯系人?七、查找聯系人?八、刪除聯系人?九、修改聯系人?十、查看所有聯系人?十一、清空所有聯系人?十二、以名字排序所有...
摘要:前言我們需要用語言模擬一個通訊錄可以用來存儲個人的信息每個人的信息包括姓名電話性別住址年齡功能包括新增聯系人查找聯系人刪除聯系人修改聯系人查看所有聯系人以名字排序所有聯系人注此版本不包含其他內容,后續會出更加全面的升級版本通訊錄語言簡易版 前言: 我們需要用C語言模擬一個通訊錄可以用來存...
閱讀 1847·2021-11-22 15:25
閱讀 3912·2021-11-17 09:33
閱讀 2507·2021-10-12 10:12
閱讀 1802·2021-10-09 09:44
閱讀 3235·2021-10-08 10:04
閱讀 1313·2021-09-29 09:35
閱讀 1947·2019-08-30 12:57
閱讀 1303·2019-08-29 16:22