C語言模擬實現(xiàn)通訊錄程序過程
一、前言
在上一章的結(jié)構(gòu)體的學(xué)習(xí)中,相信小伙伴們或多或少都有所收獲,但是有的小伙伴可能會問,結(jié)構(gòu)體到底能用來做什么呢?今天,我們就借助結(jié)構(gòu)體和之前所學(xué)的知識來實現(xiàn)通訊錄。
二、正文
1.大體框架
相信在座的小伙伴們一定有人做過類似的小游戲或項目,編程的大忌就是將所有的代碼都放在同一個文件里,寫的時候有多好爽快,后期對代碼進(jìn)行修改和維護(hù)的時候就有痛苦。這期通訊錄的實現(xiàn)我們大致分為三個模塊,一個用于測試通訊錄,即對各種函數(shù)的調(diào)用【text.c】;另一個用于通訊錄的實現(xiàn),其中放置著通訊錄功能的具體實現(xiàn)【contact.c】;最后一個就是函數(shù)的聲明了[contact.h].
2.界面顯示
就像之前的掃雷與三子棋游戲一樣,這個通訊錄的第一步一定是要讓使用者看到通訊錄的頁面,繼而在使用者選擇之后進(jìn)行下一步的操作。因而我們?nèi)耘f采取do while 循環(huán),先將頁面顯示,再根據(jù)使用者的輸入進(jìn)行相應(yīng)的操作。具體實現(xiàn)代碼如下:
void bubble_sort(int arr[], int sz) { //趟數(shù) int i = 0; for (i = 0; i < sz - 1; i++) { //一趟冒泡排序的過程 int j = 0; for (j = 0; j < sz - 1 - i; j++) { if (arr[j] > arr[j + 1]) { int tmp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = tmp; } } } }
在以上代碼的邏輯下,使用者剛開始就能夠看到我們設(shè)置好的界面,并進(jìn)行功能的輸入,如果輸入為0就退出通訊錄,通訊錄為功能相應(yīng)的數(shù)字就進(jìn)行相應(yīng)的功能【還未填寫完整】,若為其他數(shù)字,則重新輸入。
3. 創(chuàng)建通訊錄
為了實現(xiàn)我們菜單中的各個功能,首先我們要有這些功能的受體——通訊錄,只有創(chuàng)建好通訊錄 ,才能進(jìn)行功能的操作。在生活中,我們手機(jī)上的通訊錄都存有聯(lián)系人的相關(guān)信息,例如姓名,年齡,性別,手機(jī)號碼等等 ,其次在后面的功能中我們還需要知道這個通訊錄中聯(lián)系人的數(shù)量是多少。顯然,我們需要一個自定義結(jié)構(gòu)變量來定義通訊錄,在這個結(jié)構(gòu)體中有兩個變量,一個是存放聯(lián)系人信息的變量,另一個是存放聯(lián)系人數(shù)量的變量。而存放聯(lián)系人的信息顯然需要一個數(shù)組,數(shù)組的大小即對應(yīng)著能存放多少聯(lián)系人,而數(shù)組中的元素就是聯(lián)系人的信息,這也無法用一個單一類型變量來定義,所以我們還需要額外定義一個結(jié)構(gòu)體變量來代表聯(lián)系人的各種信息。具體代碼如下:
//結(jié)構(gòu)體——聯(lián)系人的信息 struct peo { char name[20]; //姓名 char sex[10]; //性別 int age; //年齡 char addr[40]; //地址 char tel[20]; //電話 }; //結(jié)構(gòu)體——通訊錄 typedef struct contact { struct peo Peo[contact_num]; //通訊錄中聯(lián)系人的信息 int sz; //當(dāng)前存放聯(lián)系人的個數(shù) }contact;
4.初始化通訊錄
在通訊錄的創(chuàng)建之后,就是對其的初始化了,為了方便,我們就都置成0就好了。
//Init_Contact——初始化通訊錄 void Init_Contact(contact* pc) { pc->sz = 0; memset(pc, 0, sizeof(pc->Peo)); }
5.增加聯(lián)系人
在通訊錄的創(chuàng)建和初始化完成之后,就是通訊錄功能的實現(xiàn)了。首先是“增加聯(lián)系人”這一功能。我們先是定義一個函數(shù),這個函數(shù)的參數(shù)就是我們的通訊錄,采用傳遞通訊錄地址的方式,返回值為空,因為我們只是對通訊錄的內(nèi)容進(jìn)行改變,并不需要返回任何東西。然后是函數(shù)的具體實現(xiàn),我們要做的是在聯(lián)系人信息這一數(shù)組中添加一個聯(lián)系人,并在添加之后將通訊錄當(dāng)前存儲的聯(lián)系人數(shù)量+1。此外如果通訊錄已滿,我們需要提醒使用者無法再添加聯(lián)系人。具體代碼如下:
//Add——增加聯(lián)系人 void Add(contact* Contact) { assert(Contact); if (Contact->sz < contact_num) { printf("請輸入聯(lián)系人的姓名:>\n"); scanf("%s", (Contact->Peo[Contact->sz]).name); printf("請輸入聯(lián)系人的性別:>\n"); scanf("%s", Contact->Peo[Contact->sz].sex); printf("請輸入聯(lián)系人的年齡:>\n"); scanf("%d", &(Contact->Peo[Contact->sz].age)); printf("請輸入聯(lián)系人的地址:>\n"); scanf("%s", Contact->Peo[Contact->sz].addr); printf("請輸入聯(lián)系人的電話:>\n"); scanf("%s", Contact->Peo[Contact->sz].tel); Contact->sz++; } else printf("通訊錄已滿無法添加\n"); }
6.顯示聯(lián)系人
為了觀察我們在執(zhí)行增加聯(lián)系人這個函數(shù)是否成功,我們接下來進(jìn)行“顯示聯(lián)系人”這一功能的實現(xiàn)。同樣的先是定義顯示聯(lián)系人這一函數(shù),函數(shù)參數(shù)是通訊錄,采取傳址調(diào)用的方式,無需返回任何參數(shù)。函數(shù)的實現(xiàn)就是依據(jù)通訊錄中所存儲的聯(lián)系人數(shù)量,來調(diào)用存儲聯(lián)系人信息的數(shù)組,并將其顯示在屏幕上,為了數(shù)據(jù)顯示的整齊和美觀,筆者對打印的數(shù)據(jù)類型進(jìn)行了小小的改善,對數(shù)據(jù)所占空間進(jìn)行了設(shè)置,并將數(shù)據(jù)左對齊并在數(shù)據(jù)后輸出一個水平制表符。
//Show——展示聯(lián)系人 void Show( const contact* Contact) { assert(Contact); int pos = 0; //聯(lián)系人對應(yīng)下標(biāo) printf("%-20s\t%-10s\t%-4s\t%-40s\t%-20s\n","姓名", "性別", "年齡", "地址", "電話"); for (pos = 0; pos < Contact->sz; pos++) { printf("%-20s\t%-10s\t%-4d%\t%-40s\t%-20s\n", Contact->Peo[pos].name, Contact->Peo[pos].sex, Contact->Peo[pos].age, Contact->Peo[pos].addr, Contact->Peo[pos].tel); } }
7. 刪除聯(lián)系人
首先是“刪除聯(lián)系人”這一函數(shù)的定義,參數(shù)為通訊錄這一結(jié)構(gòu)體,采取傳址調(diào)用的方式,返回參數(shù)無。繼而是函數(shù)具體的實現(xiàn),筆者是根據(jù)使用者所輸入的所要刪除聯(lián)系人的姓名來找到聯(lián)系人在數(shù)組中對應(yīng)的下標(biāo),從而進(jìn)行各項信息的刪除。這里有個小技巧,無論是刪除聯(lián)系人,修改聯(lián)系人,搜索聯(lián)系人都需要在根據(jù)輸入的姓名對聯(lián)系人進(jìn)行查找,因而我們可以將這個功能封裝成一個函數(shù),在使用這一功能的時候只需要調(diào)用就行了。具體代碼實現(xiàn)如下:
//Find_by_name——通過姓名,找到聯(lián)系人所對應(yīng)的下標(biāo) int Find_by_name( const contact* Contact, char *name) { int i = 0; for (i = 0; i < Contact->sz; i++) { if (strcmp(&(Contact->Peo[i].name),name)==0) return i; } return -1; } //Del——刪除聯(lián)系人 void Del(contact* Contact) { char name[20] = { 0 }; int i = 0; printf("請輸入要刪除的聯(lián)系人:>"); scanf("%s", name); int pos = Find_by_name(Contact, &name); if (-1 == pos) { printf("該聯(lián)系人不存在\n"); return; } else { for (i = pos; i < Contact->sz-1; i++) { Contact->Peo[i] = Contact->Peo[i + 1]; } Contact->sz--; } }
8.查找聯(lián)系人
首先是對“查找聯(lián)系人”函數(shù)的定義,函數(shù)參數(shù)為通訊錄,采取傳址調(diào)用的方式,返回參數(shù)為0。然后是具體功能的實現(xiàn),先是根據(jù)輸入的姓名查找到對應(yīng)的下標(biāo),再將其顯示在屏幕上。具體代碼如下:
//Search——搜索聯(lián)系人 void Search(const contact* Contact) { char name[20] = {0}; printf("請輸入要尋找的聯(lián)系人:>"); scanf("%s", name); int pos= Find_by_name(Contact, &name); if (-1==pos) { printf("該聯(lián)系人不存在\n"); return; } else { printf("%-10s\t%-6s\t%-4s\t%-40s\t%-20s\n", "姓名", "性別", "年齡", "地址", "電話"); printf("%-10s\t%-6s\t%-4d%\t%-40s\t%-20s\n", Contact->Peo[pos].name, Contact->Peo[pos].sex, Contact->Peo[pos].age, Contact->Peo[pos].addr, Contact->Peo[pos].tel); } }
9.修改聯(lián)系人
首先是對“修改聯(lián)系人”函數(shù)的定義,函數(shù)參數(shù)為通訊錄,采取傳址調(diào)用的方式,返回參數(shù)為0。然后是具體功能的實現(xiàn),先是根據(jù)輸入的姓名查找到對應(yīng)的下標(biāo),再依據(jù)添加聯(lián)系人的代碼實現(xiàn)聯(lián)系人信息的修改。具體代碼如下:
//Modify——修改聯(lián)系人 void Modify(contact* Contact) { assert(Contact); char name[20] = { 0 }; printf("請輸入要修改的聯(lián)系人\n"); scanf("%s", name); int pos = Find_by_name(Contact, &name); if (-1 == pos) { printf("該聯(lián)系人不存在\n"); return; } else { printf("請輸入聯(lián)系人的姓名:>\n"); scanf("%s", (Contact->Peo[pos]).name); printf("請輸入聯(lián)系人的性別:>\n"); scanf("%s", Contact->Peo[pos].sex); printf("請輸入聯(lián)系人的年齡:>\n"); scanf("%d", &(Contact->Peo[pos].age)); printf("請輸入聯(lián)系人的地址:>\n"); scanf("%s", Contact->Peo[pos].addr); printf("請輸入聯(lián)系人的電話:>\n"); scanf("%s", Contact->Peo[pos].tel); } }
10. 排序聯(lián)系人
對聯(lián)系人排序依據(jù)有很多,這里僅對聯(lián)系人的年齡進(jìn)行排序。采取冒泡排序的方式,冒泡排序的實現(xiàn)在前面的推文已經(jīng)介紹過了,有興趣的小伙伴可以康一康。http://www.dbjr.com.cn/article/275286.htm
//sort——按照年齡對聯(lián)系人進(jìn)行排序 void sort(contact* Contact,contact* tmp) { //執(zhí)行冒泡排序的趟數(shù) int i = 0; for (i = 0; i < Contact->sz - 1; i++) { //一趟冒泡排序中交換的次數(shù) int j = 0; for (j = 0; j < Contact->sz - 1-i; j++) { if (Contact->Peo[j].age > Contact->Peo[j + 1].age) { tmp->Peo[0] = Contact->Peo[j]; Contact->Peo[j] = Contact->Peo[j + 1]; Contact->Peo[j + 1] = tmp->Peo[0]; } } } }
到這里,整個通訊錄就寫完了,整體的代碼如下:
//main.c #include "contact.h" //菜單 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"); } int main() { contact Contact; //創(chuàng)建通訊錄 contact tmp; Init_Contact(&Contact); //初始化通訊錄 Init_Contact(&tmp); int input = 0; do { menu(); //打印菜單 printf("請選擇你所需的功能:"); scanf("%d", &input); switch (input) { case 1: Add(&Contact); break; case 2: Del(&Contact); break; case 3: Search(&Contact); break; case 4: Modify(&Contact); break; case 5: Show(&Contact); break; case 6: sort(&Contact,&tmp); break; case 0: printf("退出通訊錄\n"); break; default: printf("輸入錯誤,請重新輸入\n"); } } while (input); return 0; } //contact.h #define _CRT_SECURE_NO_WARNINGS 1 #pragma once #define contact_num 100 #include <stdio.h> #include <string.h> #include <assert.h> //結(jié)構(gòu)體——聯(lián)系人的信息 struct peo { char name[20]; //姓名 char sex[10]; //性別 int age; //年齡 char addr[40]; //地址 char tel[20]; //電話 }; //結(jié)構(gòu)體——通訊錄 typedef struct contact { struct peo Peo[contact_num]; //通訊錄中聯(lián)系人的信息 int sz; //當(dāng)前存放聯(lián)系人的個數(shù) }contact; void Init_Contact(contact* pc); //初始化通訊錄 void Add(contact* Contact); //添加聯(lián)系人 void Show(const contact* Contact); //展示聯(lián)系人 void Search(const contact* Contact); //搜索聯(lián)系人 void Del(contact* Contact); //刪除聯(lián)系人 void Modify(contact* Contact); //修改聯(lián)系人 void sort(contact* Contact,contact* tmp); //排序聯(lián)系人——年齡 //contact.c #include "contact.h" //Init_Contact——初始化通訊錄 void Init_Contact(contact* pc) { pc->sz = 0; memset(pc, 0, sizeof(pc->Peo)); } //Add——增加聯(lián)系人 void Add(contact* Contact) { assert(Contact); if (Contact->sz < contact_num) { printf("請輸入聯(lián)系人的姓名:>\n"); scanf("%s", (Contact->Peo[Contact->sz]).name); printf("請輸入聯(lián)系人的性別:>\n"); scanf("%s", Contact->Peo[Contact->sz].sex); printf("請輸入聯(lián)系人的年齡:>\n"); scanf("%d", &(Contact->Peo[Contact->sz].age)); printf("請輸入聯(lián)系人的地址:>\n"); scanf("%s", Contact->Peo[Contact->sz].addr); printf("請輸入聯(lián)系人的電話:>\n"); scanf("%s", Contact->Peo[Contact->sz].tel); Contact->sz++; } else printf("通訊錄已滿無法添加\n"); } //Show——展示聯(lián)系人 void Show( const contact* Contact) { assert(Contact); int pos = 0; printf("%-10s\t%-6s\t%-4s\t%-40s\t%-20s\n","姓名", "性別", "年齡", "地址", "電話"); for (pos = 0; pos < Contact->sz; pos++) { printf("%-10s\t%-6s\t%-4d%\t%-40s\t%-20s\n", Contact->Peo[pos].name, Contact->Peo[pos].sex, Contact->Peo[pos].age, Contact->Peo[pos].addr, Contact->Peo[pos].tel); } } //Find_by_name——通過姓名,找到聯(lián)系人所對應(yīng)的下標(biāo) int Find_by_name( const contact* Contact, char *name) { int i = 0; for (i = 0; i < Contact->sz; i++) { if (strcmp(&(Contact->Peo[i].name),name)==0) return i; } return -1; } //Search——搜索聯(lián)系人 void Search(const contact* Contact) { char name[20] = {0}; printf("請輸入要尋找的聯(lián)系人:>"); scanf("%s", name); int pos= Find_by_name(Contact, &name); if (-1==pos) { printf("該聯(lián)系人不存在\n"); return; } else { printf("%-10s\t%-6s\t%-4s\t%-40s\t%-20s\n", "姓名", "性別", "年齡", "地址", "電話"); printf("%-10s\t%-6s\t%-4d%\t%-40s\t%-20s\n", Contact->Peo[pos].name, Contact->Peo[pos].sex, Contact->Peo[pos].age, Contact->Peo[pos].addr, Contact->Peo[pos].tel); } } //Del——刪除聯(lián)系人 void Del(contact* Contact) { char name[20] = { 0 }; int i = 0; printf("請輸入要刪除的聯(lián)系人:>"); scanf("%s", name); int pos = Find_by_name(Contact, &name); if (-1 == pos) { printf("該聯(lián)系人不存在\n"); return; } else { for (i = pos; i < Contact->sz-1; i++) { Contact->Peo[i] = Contact->Peo[i + 1]; } Contact->sz--; } } //Modify——修改聯(lián)系人 void Modify(contact* Contact) { assert(Contact); char name[20] = { 0 }; printf("請輸入要修改的聯(lián)系人\n"); scanf("%s", name); int pos = Find_by_name(Contact, &name); if (-1 == pos) { printf("該聯(lián)系人不存在\n"); return; } else { printf("請輸入聯(lián)系人的姓名:>\n"); scanf("%s", (Contact->Peo[pos]).name); printf("請輸入聯(lián)系人的性別:>\n"); scanf("%s", Contact->Peo[pos].sex); printf("請輸入聯(lián)系人的年齡:>\n"); scanf("%d", &(Contact->Peo[pos].age)); printf("請輸入聯(lián)系人的地址:>\n"); scanf("%s", Contact->Peo[pos].addr); printf("請輸入聯(lián)系人的電話:>\n"); scanf("%s", Contact->Peo[pos].tel); } } //sort——按照年齡對聯(lián)系人進(jìn)行排序 void sort(contact* Contact,contact* tmp) { //執(zhí)行冒泡排序的趟數(shù) int i = 0; for (i = 0; i < Contact->sz - 1; i++) { //一趟冒泡排序中交換的次數(shù) int j = 0; for (j = 0; j < Contact->sz - 1-i; j++) { if (Contact->Peo[j].age > Contact->Peo[j + 1].age) { tmp->Peo[0] = Contact->Peo[j]; Contact->Peo[j] = Contact->Peo[j + 1]; Contact->Peo[j + 1] = tmp->Peo[0]; } } } }
到此這篇關(guān)于C語言模擬實現(xiàn)通訊錄程序過程的文章就介紹到這了,更多相關(guān)C語言通訊錄內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
c++ 獲取數(shù)字字符串的子串?dāng)?shù)值性能示例分析
這篇文章主要為大家介紹了c++ 獲取數(shù)字字符串的子串?dāng)?shù)值示例分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-11-11C++回調(diào)函數(shù)實現(xiàn)計算器和qsort
這篇文章主要介紹了C++回調(diào)函數(shù)實現(xiàn)計算器和qsort,回調(diào)函數(shù)就是一個通過函數(shù)指針調(diào)用的函數(shù)。如果你把函數(shù)的指針(地址)作為參數(shù)傳遞給另一個函數(shù),當(dāng)這個指針被用來調(diào)用其所指向的函數(shù)時,我們就說這是回調(diào)函數(shù)2022-08-08C++從文本文件讀取數(shù)據(jù)到vector中的方法
這篇文章主要給大家介紹了利用C++如何從文本文件讀取數(shù)據(jù)到vector中,文章通過實例給出示例代碼,相信會對大家的理解和學(xué)習(xí)很有幫助,有需要的朋友們下面來一起看看吧。2016-10-10