用c語言編寫一個通訊錄代碼詳解
實現(xiàn)通訊錄的思路如下:
1.程序運行起來時用戶首先要看到菜單欄選項并且對應(yīng)菜單欄所給出的選項做出選擇,這里我們簡單設(shè)計一個Menu()函數(shù)可以讓用戶看見可選項目;
2.用戶可選的范圍應(yīng)該是1~7,為了避免用戶做出超出范圍的選擇我們可以用switch語句來判斷用戶的選擇若用戶輸入的數(shù)字非法還可以讓用戶繼續(xù)選擇,而繼續(xù)選擇這個動作需要用到while語句,用戶對通訊錄的不斷操作也需要用到while語句;
3.用戶選擇不同的選項,程序就要調(diào)用對應(yīng)的函數(shù)來實現(xiàn)其功能并且我們對switch語句進(jìn)行優(yōu)化,如果直接對輸入的數(shù)字進(jìn)行判斷的話我們還需要對照直接設(shè)計的菜單欄選項對捕捉到的用戶選擇做出判斷需要不是參考菜單欄,為了解決這個問題,我們用枚舉的方法來提高代碼的可讀性;
enum menu { ADD = 1, SHOW, MODIFIES, FIND, DELETE, SORT, EXITS, };
4.接下來我們對通訊錄的功能一一實現(xiàn),不難想到要對通訊錄中的聯(lián)系人信息進(jìn)行操作就必須要有存放聯(lián)系人信息的載體,而每個聯(lián)系人信息則又包含姓名,年齡,性別,電話號碼,地址這些信息,所以我們首先自定義一個message類型,然后創(chuàng)建一個message數(shù)組來存放聯(lián)系人信息,數(shù)組的大小由我們自行設(shè)定最好用#define來設(shè)定num的大小可以做到一改全改。
#define num 100 typedef struct s { int age; char name[10]; char number[20]; char sex[5]; char adress[20]; }message;
5.添加聯(lián)系人功能:要想添加聯(lián)系人就得對保存所有聯(lián)系人信息的數(shù)組進(jìn)行操作并且還要知道把新建的聯(lián)系人信息存入數(shù)組的第幾個元素中,所以這個AddMessage函數(shù)應(yīng)該接收這兩個參數(shù),考慮到要統(tǒng)計通訊錄中聯(lián)系人的個數(shù)并且在添加聯(lián)系人成功后該個數(shù)應(yīng)該++,所以在創(chuàng)建聯(lián)系人數(shù)組的同時應(yīng)該同時定義一個變量來告訴一些功能函數(shù)通訊錄中聯(lián)系人的個數(shù)并且在addMessage這個函數(shù)中還需要對這個變量的值進(jìn)行+1操作所以我們應(yīng)該向這個函數(shù)傳入該變量的地址達(dá)到修改變量值的目的。
void MyScanf(message arr[num], int* i) { printf("請輸入聯(lián)系人姓名:\n"); scanf("%s", (arr[*i].name)); printf("請輸入聯(lián)系人年齡:\n"); scanf("%d", &(arr[*i].age)); printf("請輸入聯(lián)系人電話號碼:\n"); scanf("%s", (arr[*i].number)); printf("請輸入聯(lián)系人性別:\n"); scanf("%s", (arr[*i].sex)); printf("請輸入聯(lián)系人地址:\n"); scanf("%s", (arr[*i].adress)); } void AddMessage(message arr[num],int* i ) { MyScanf(arr,i); (*i)++; }
6.向用戶展示當(dāng)前所有聯(lián)系人的功能:這個功能很容易實現(xiàn)(就是對數(shù)組元素的遍歷)Show函數(shù)只需要知道聯(lián)系人數(shù)組中有多少個元素和該數(shù)組的地址即可對其完成遍歷再將遍歷出來的信息打印出來即可,這里不再贅述,直接上代碼。
void MyPrintf(message arr[num],int j) { printf("%s ", arr[j].name); printf("%d ", arr[j].age); printf("%s ", arr[j].number); printf("%s ", arr[j].sex); printf("%s ", arr[j].adress); printf("\n"); } void Show(message arr[num],int i) { for (int j = 0;j < i;j++) { MyPrintf(arr, j); } }
7.修改聯(lián)系人信息功能:眾所周知,要對已有的練習(xí)人信息進(jìn)行修改則應(yīng)該先找到要修改的聯(lián)系人信息,首先我們根據(jù)用戶輸入的要修改的聯(lián)系人姓名找到該聯(lián)系人的數(shù)組索引值然后對其重新錄入信息(與添加聯(lián)系人信息時的錄入方式相同),如果通訊錄中沒有找到要修改的聯(lián)系人則提示用戶通訊錄中沒有此人的信息。
void Modifies(message arr[num],int* i) { printf("請輸入你要修改的聯(lián)系人名字:\n"); char arr1[10] = { 0 }; scanf("%s", arr1); int k = 0; for (int j = 0;j < (*i);j++) { if (strcmp(arr1, arr[j].name) == 0) { k = 1; MyPrintf(arr, j); int* a = &j; MyScanf(arr, a); } } if (k == 0) { printf("通訊錄中沒有此人?。?!\n"); } }
8.查找聯(lián)系人信息:這個功能的實現(xiàn)特別簡單無非就是遍歷聯(lián)系人數(shù)組找到與用戶查找信息匹配的聯(lián)系人并且打印該聯(lián)系人的信息,如果遍歷整個聯(lián)系人數(shù)組也沒有找到同樣提示通訊錄中沒有該聯(lián)系人。
void Find(message arr[num],int i) { char arr1[10] = {0}; printf("請輸入要查找的聯(lián)系人姓名:\n"); scanf("%s",arr1); int k = 0; for (int j = 0;j < i;j++) { if (strcmp(arr1, arr[j].name) == 0) { k = 1; MyPrintf(arr, j); } } if (k == 0) { printf("通訊錄中沒有此人!??!\n"); } }
9.刪除聯(lián)系人信息:同樣的要刪除通訊錄中的聯(lián)系人先要找到該聯(lián)系人的位置如果沒有找到則提示用戶通訊錄中沒有該聯(lián)系人的信息,如果找到了則應(yīng)該先向用戶展示該聯(lián)系人的信息再次詢問用戶是否確定刪除該聯(lián)系人,如果用戶確定刪除則進(jìn)行下一步,要想抹掉這個數(shù)據(jù)需要對數(shù)據(jù)的位置判斷如果該聯(lián)系人是最后一個聯(lián)系人(在通訊錄現(xiàn)有的聯(lián)系人中位置拍最后),則只需要對通訊錄中的聯(lián)系人個數(shù)-1這樣一來用戶除了添加聯(lián)系人操作之外都無法對該位置的元素進(jìn)行訪問,而添加聯(lián)系人時就在該位置進(jìn)行添加正好抹除這個元素的信息,讓新添加的聯(lián)系人取而代之。如果該元素所在的位置不是通訊錄的末尾位置則將其后一個位置的元素拷貝到它所在的位置,讓它后面元素的位置都向前移動一位,完成這項操作之后再讓聯(lián)系人個數(shù)-1即可。
int Delete(message arr[num], int* i) { char arr1[10] = { 0 }; printf("請輸入要刪除的聯(lián)系人姓名:\n"); scanf("%s", arr1); for (int j = 0;j < (*i);j++) { if (strcmp(arr1, arr[j].name) == 0) { MyPrintf(arr, j); int a = 0; printf(" 確認(rèn)刪除嗎?\n"); printf("****1.YES****\n"); printf("****2.NO ****\n"); scanf("%d",&a); if (a == 1) { if ((j + 1) < (*i)) { for (int k = j;k < (*i) - 1;k++) { arr[k] = arr[k + 1]; } } (*i)--; } else { return -1; } return 1; } } printf("通訊錄中沒有此人!??!\n"); return -1; }
10.對聯(lián)系人信息按名字字母進(jìn)行排序,排序是一個老生常談的問題,這里我們直接用冒泡排序?qū)σ延新?lián)系人信息進(jìn)行排序,無非在判斷是否要交換元素位置的時候用到了strcmp函數(shù)。
void SortByname(message arr[num], int i) { for (int j = 0;j < i - 1;j++) { for (int k = 0;k < i - j - 1;k++) { if (strcmp(arr[k].name,arr[k+1].name) > 0) { message a = arr[k+1]; arr[k + 1] = arr[k]; arr[k] = a; } } } }
存在的問題:進(jìn)入程序就創(chuàng)建了一個元素個數(shù)為num的message類型的數(shù)組,如果num很大的話程序能不能運行起來就是一個問題,即使程序運行起來,如果我只添加了幾個聯(lián)系人而這個程序卻為該數(shù)組開辟了大量空間造成了內(nèi)存的浪費,另一個極端條件假如我要添加10000個聯(lián)系人的信息那么顯然這個程序壓根就跑不起來因為無法給message數(shù)組開辟10000個聯(lián)系人的空間大小,那么我們該如何改進(jìn)這個通訊錄呢?請看下一篇文章。
下面我們給出所有的代碼
頭文件:
#include<stdio.h> #include<string.h> #include<stdlib.h> #pragma once #pragma warning (disable:4996) #define num 100 enum menu { ADD = 1, SHOW, MODIFIES, FIND, DELETE, SORT, EXITS, }; typedef struct s { int age; char name[10]; char number[20]; char sex[5]; char adress[20]; }message; extern void Choose(); extern void AddMessage(message arr[num],int*); extern void Show(message arr[num], int); extern void Find(message arr[num],int); extern void MyPrintf(message arr[num], int); extern void Modifies(message arr[num],int*); extern int Delete(message arr[num], int*); extern void SortByname(message arr[num], int);
main函數(shù):
#include "AddressBook.h" #pragma once void Choose() { printf("********1.添加新聯(lián)系人**********\n"); printf("********2.展示已有聯(lián)系人********\n"); printf("********3.修改聯(lián)系人信息********\n"); printf("********4.查找聯(lián)系人信息********\n"); printf("********5.刪除聯(lián)系人************\n"); printf("********6.對已有聯(lián)系人排序******\n"); printf("********7.退出通訊錄************\n"); } int main() { message arr[num]; int b = 0; while (1) { Choose(); int i = 0; printf("請輸入你的選擇:\n"); scanf("%d", &i); switch (i) { case ADD : AddMessage(arr,&b); break; case SHOW: Show(arr,b); break; case MODIFIES: Modifies(arr,&b); break; case FIND: Find(arr,b); break; case DELETE: Delete(arr,&b); break; case SORT: SortByname(arr,b); break; case EXITS: exit(0); break; default : printf("你的選擇有誤,重新選擇!\n"); i = 0; break; } } return 0; }
菜單功能函數(shù):
#pragma once #include "AddressBook.h" void MyScanf(message arr[num], int* i) { printf("請輸入聯(lián)系人姓名:\n"); scanf("%s", (arr[*i].name)); printf("請輸入聯(lián)系人年齡:\n"); scanf("%d", &(arr[*i].age)); printf("請輸入聯(lián)系人電話號碼:\n"); scanf("%s", (arr[*i].number)); printf("請輸入聯(lián)系人性別:\n"); scanf("%s", (arr[*i].sex)); printf("請輸入聯(lián)系人地址:\n"); scanf("%s", (arr[*i].adress)); } void AddMessage(message arr[num],int* i ) { MyScanf(arr,i); (*i)++; } void Show(message arr[num],int i) { for (int j = 0;j < i;j++) { MyPrintf(arr, j); } } void Find(message arr[num],int i) { char arr1[10] = {0}; printf("請輸入要查找的聯(lián)系人姓名:\n"); scanf("%s",arr1); int k = 0; for (int j = 0;j < i;j++) { if (strcmp(arr1, arr[j].name) == 0) { k = 1; MyPrintf(arr, j); } } if (k == 0) { printf("通訊錄中沒有此人?。?!\n"); } } void MyPrintf(message arr[num],int j) { printf("%s ", arr[j].name); printf("%d ", arr[j].age); printf("%s ", arr[j].number); printf("%s ", arr[j].sex); printf("%s ", arr[j].adress); printf("\n"); } void Modifies(message arr[num],int* i) { printf("請輸入你要修改的聯(lián)系人名字:\n"); char arr1[10] = { 0 }; scanf("%s", arr1); int k = 0; for (int j = 0;j < (*i);j++) { if (strcmp(arr1, arr[j].name) == 0) { k = 1; MyPrintf(arr, j); int* a = &j; MyScanf(arr, a); } } if (k == 0) { printf("通訊錄中沒有此人!?。n"); } } int Delete(message arr[num], int* i) { char arr1[10] = { 0 }; printf("請輸入要刪除的聯(lián)系人姓名:\n"); scanf("%s", arr1); for (int j = 0;j < (*i);j++) { if (strcmp(arr1, arr[j].name) == 0) { MyPrintf(arr, j); int a = 0; printf(" 確認(rèn)刪除嗎?\n"); printf("****1.YES****\n"); printf("****2.NO ****\n"); scanf("%d",&a); if (a == 1) { if ((j + 1) < (*i)) { for (int k = j;k < (*i) - 1;k++) { arr[k] = arr[k + 1]; } } (*i)--; } else { return -1; } return 1; } } printf("通訊錄中沒有此人!!!\n"); return -1; } void SortByname(message arr[num], int i) { for (int j = 0;j < i - 1;j++) { for (int k = 0;k < i - j - 1;k++) { if (strcmp(arr[k].name,arr[k+1].name) > 0) { message a = arr[k+1]; arr[k + 1] = arr[k]; arr[k] = a; } } } }
總結(jié)
到此這篇關(guān)于用c語言編寫一個通訊錄代碼詳解的文章就介紹到這了,更多相關(guān)c語言通訊錄內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C和C++中的基本數(shù)據(jù)類型的大小及表示范圍詳解
這篇文章主要介紹了C和C++中的基本數(shù)據(jù)類型的大小及表示范圍詳解,基本數(shù)據(jù)類型有int、long、long long、float、double、char、string,正文有詳細(xì)介紹,歡迎參考2018-01-01C++Primer筆記之關(guān)聯(lián)容器的使用詳解
本篇文章對C++Primer 關(guān)聯(lián)容器的使用進(jìn)行了詳細(xì)的分析介紹。需要的朋友參考下2013-05-05Cocos2d-x學(xué)習(xí)筆記之Hello World!
這篇文章主要介紹了Cocos2d-x學(xué)習(xí)筆記之Hello World!本文基于vs2010和C++語言開發(fā),需要的朋友可以參考下2014-09-09怎么用C++提取任意一張圖片的特征(從內(nèi)存讀取數(shù)據(jù))
這篇文章主要介紹了用C++提取任意一張圖片的特征(從內(nèi)存讀取數(shù)據(jù))的相關(guān)資料,需要的朋友可以參考下2017-05-05C語言typedef與復(fù)雜函數(shù)聲明問題的深入解析
以下是對C語言中的typedef與復(fù)雜函數(shù)聲明問題進(jìn)行了詳細(xì)的分析介紹,需要的朋友可以過來參考下2013-07-07關(guān)于C/C++中的side effect(負(fù)效應(yīng))和sequence point(序列點)
不知你在寫code時是否遇到這樣的問題?int i = 3; int x = (++i) + (++i) + (++i); 問x值為多少?進(jìn)行各種理論分析,并在編譯器上實踐,然而可能發(fā)現(xiàn)最終的結(jié)果是不正確的,也是不穩(wěn)定的,不同的編譯器可能會產(chǎn)生不同的結(jié)果。這讓人很頭疼2013-10-10