基于C++實現(xiàn)三種不同版本的通訊錄
靜態(tài)版本
這個版本可以說是1.0版,畢竟后面實現(xiàn)都是在它基礎(chǔ)上實現(xiàn)改進。所以就它開始開頭練手。
這里實現(xiàn)代碼大多是語法,并沒有太多花里胡哨的,邏輯清晰直接開干。
可以試想一下,對于內(nèi)容存儲,查找無非就是根據(jù)他的特征來查找,所以確定需要存儲的變量就可以保存實現(xiàn)。通訊錄可以簡單對于名字,性別,年齡,電話號等來確定查找。
我們使用結(jié)構(gòu)體來進行整體構(gòu)造,可以用一個結(jié)構(gòu)體作為整個整體框架,框架里還有個人信息保存也需要一個結(jié)構(gòu)來進行內(nèi)容管理保存。相當于一個大柜子上有很多小抽屜。
有了框架可以直接上代碼
test.c
#include"main.h" void menu() { printf("****************************\n"); printf("***1.add 2.del*****\n"); printf("***3.serach 4.modify****\n"); printf("***5.show 6.eixt ****\n"); printf("****************************\n"); } enum option { ADD=1, DEL, SERACH, MODIFY, SHOW, EXIT }; int main() { int input = 0; struct contacts con; init_contact(&con); do { flag: menu(); printf("請選擇模式:"); scanf("%d", &input); switch (input) { case ADD: //DestroyContact(&con); addinfo(&con); break; case DEL: delinfo(&con); break; case SERACH: searchinfo(&con); break; case MODIFY: modifyinfo(&con); break; case SHOW: showinfo(&con); break; case EXIT: printf("退出\n"); // DestroyContact(&con); break; default: printf("輸入無效\n"); goto flag; break; } } while (input); return 0; }
function.c
#include"main.h" //初始化--靜態(tài)版 void init_contact(struct contacts* pcon) { assert(pcon); pcon->size = 0; memset(pcon->date, 0, size_num * sizeof(struct self_info)); } //sort int CmpByName(const void* e1,const void* e2) { return strcmp(((struct self_info*)e1)->name, ((struct self_info*)e2)->name); } void SortContact(struct contacts* pcon) { qsort(pcon->date, pcon->size, sizeof(struct self_info), CmpByName); } //1 void addinfo(struct contacts* pcon) { assert(pcon); if (pcon->size == size_num) { printf("The contacts is full\n"); } else { printf("請輸入姓名:"); scanf("%s", pcon->date[pcon->size].name); printf("請輸入年齡:"); scanf("%d",&(pcon->date[pcon->size].age));//注意取地址 printf("請輸入電話:"); scanf("%s", pcon->date[pcon->size].tele); printf("請輸入地址:"); scanf("%s", pcon->date[pcon->size].adeer); printf("請輸入性別:"); scanf("%s", pcon->date[pcon->size].sex); pcon->size++;//數(shù)組下標 printf("operation was successful\n"); } void SortContact(struct contacts* pcon); } // static int find_contactsbyname(const struct contacts* pcon, const char name[]) { int i = 0; for (i = 0; i < pcon->size; i++) { if (0 == strcmp(pcon->date[i].name, name)) { return i; } } return -1; } //2 void delinfo(struct contacts* pcon) { char name[size_num]; printf("輸入想要刪除的人名:"); scanf("%s", name); int ret=find_contactsbyname(pcon, name); if (ret == -1) { printf("no the people \n"); } else { int j = 0; for (j = ret; j < pcon->size-1; j++) { pcon->date[j] = pcon->date[j + 1]; } pcon->size--; printf("the information was delet\n"); } } //3 void searchinfo(const struct contacts* pcon) { char name[size_num]; scanf("%s", &name); printf("請輸入要查找人名:\n"); int ret = find_contactsbyname(pcon, name); if (ret == -1) { printf("no the people \n"); } else { printf("%-20s\t%-2s\t%-20s\t%-40s\t%-6s\n", "姓名", "年齡", "地址", "電話", "性別"); printf("%-20s\t%-2d\t%-20s\t%-40s\t%-6s\n", pcon->date[pcon->size].name, pcon->date[pcon->size].age, pcon->date[pcon->size].adeer, pcon->date[pcon->size].tele, pcon->date[pcon->size].sex); } } //4 void modifyinfo(struct contacts* pcon) { char name[size_num]; scanf("%s", &name); printf("請輸入要修改的人名:\n"); int ret = find_contactsbyname(pcon, name); if (ret == -1) { printf("no one"); } else { printf("請輸入姓名:"); scanf("%s", pcon->date[ret].name); printf("請輸入年齡:"); scanf("%d", &(pcon->date[ret].age));//注意取地址 printf("請輸入電話:"); scanf("%s", pcon->date[ret].tele); printf("請輸入地址:"); scanf("%s", pcon->date[ret].adeer); printf("請輸入性別:"); scanf("%s", pcon->date[ret].sex); printf("修改成功\n"); } } //5 void showinfo(const struct contacts* pcon) { printf("%-20s\t%-5s\t%-20s\t%-20s\t%-6s\n", "姓名", "年齡", "地址", "電話", "性別"); int i = 0; for (i = 0; i <=pcon->size; i++) { if(pcon->date[i].age != 0) printf("%-20s\t %-5d\t %-20s\t %-20s\t %-6s\n", pcon->date[i].name, pcon->date[i].age, pcon->date[i].adeer, pcon->date[i].tele, pcon->date[i].sex); } }
fuction.h
#include<stdio.h> #include<string.h> #include<assert.h> #include<stdlib.h> #include<errno.h> //靜態(tài)版 #define size_num 100 //信息大小 #define size_name 20 #define size_sex 6 #define size_adeer 20 #define num_tele 12 //個人信息 struct self_info { char name[size_name]; char sex[size_sex]; char tele[num_tele]; int age; char adeer[size_adeer]; }; //靜態(tài)版本 //struct contacts //{ // struct self_info date[size_num]; // int size; //}; //初始化 void init_contact(struct contacts* pcon); //增加 void addinfo(struct contacts* pcon); //刪除 void delinfo(struct contacts* pcon); //查找 int find_contactsbyname(struct contacts* pcon, char* name[]); void searchinfo(const struct contacts* pcon); //展示 void showinfo(const struct contacts* pcon); //修改 void modifyinfo(struct contacts* pcon); //sort void SortContact(struct contacts* pcon);
動態(tài)版本
這里我們是在靜態(tài)版本上升級改動而來,在后面我們實現(xiàn)代碼時發(fā)現(xiàn),假如我們輸入地址比較詳細或者名字太長時間,就需要我們不停更改頭文件中內(nèi)容,所以為了能夠減少對于代碼修改。所以我們就可以用動態(tài)內(nèi)存開辟。
在function.h中加入
//銷毀 void DestroyContact(struct contacts* pcon);
在靜態(tài)版本function.c中加入
//動態(tài)版 //void init_contact(struct contacts* pcon) //{ // assert(pcon); // pcon->date=(struct self_info*)malloc(defalut_size * sizeof(struct self_info)); // if (pcon->date == NULL) // { // perror("init_contact()"); // return; // } // int size = 0; // int capacity = defalut_size; //} // 銷毀 //void DestroyContact(struct contacts* pcon) //{ // free(pcon->date); // pcon->date = NULL; // pcon->capacity = 0; // pcon->size = 0; //}
還有函數(shù)addinfo前加入,檢查開辟空間是否足夠,避免越界訪問。
//static int chack_capacity(struct contacts* pcon) //{ // if (pcon->size == pcon->capacity) // { // //增容是增加信息 // struct self_info* str = (struct self_info*)realloc(pcon->date, (alterable_size + pcon->capacity) * sizeof(struct self_info)); // if (str != NULL) // { // pcon->date = str; // pcon->capacity += alterable_size; // printf("擴容成功,內(nèi)存足夠,放心使用\n"); // return 1; // } // else // { // perror("chack_capacity()"); // return 0; // } // } // else // { // return 1; // } // //}
便可以實現(xiàn)動態(tài)開辟內(nèi)存。
文件版本
這里可以實現(xiàn)文件形式保存,前面版本是基于程序使用,程序關(guān)閉數(shù)據(jù)也會消失。這里會在對應(yīng)文件目錄下,生成一個txt文本,便于觀察。這里需要對于文件操作有一定了解。對于文件寫入與輸出函數(shù)的參數(shù)了解和熟悉。本次使用函數(shù)有以下函數(shù)。
文件打開函數(shù): fopen
文件關(guān)閉函數(shù): fclose
二進制輸入函數(shù): fwrite
二進制輸出函數(shù): fread
代碼如下
#define _CRT_SECURE_NO_WARNINGS 1 #include "contact.h" //靜態(tài)的版本 //void InitContact(struct Contact* pc) //{ // assert(pc); // pc->sz = 0; // memset(pc->data, 0, MAX *sizeof(struct PeoInfo)); //} static int check_capacity(struct Contact* pc); void LoadContact(struct Contact* pc) { //打開文件 FILE*pfR = fopen("data.txt", "rb"); if (pfR == NULL) { perror("LoadContact::fopen"); return; } //讀文件 struct PeoInfo tmp = { 0 }; while (fread(&tmp, sizeof(struct PeoInfo), 1, pfR)) { //考慮增加容量的問題 check_capacity(pc); pc->data[pc->sz] = tmp; pc->sz++; } //關(guān)閉文件 fclose(pfR); pfR = NULL; } void InitContact(struct Contact* pc) { assert(pc); pc->data = (struct PeoInfo*)malloc(DEFAULT_SZ * sizeof(struct PeoInfo)); if (pc->data == NULL) { perror("InitContact()"); return; } pc->sz = 0; pc->capacity = DEFAULT_SZ; //加載文件中的信息,到通訊錄中 LoadContact(pc); } void DestroyContact(struct Contact* pc) { free(pc->data); pc->data = NULL; pc->capacity = 0; pc->sz = 0; } //靜態(tài)的版本 //void AddContact(struct Contact* pc) //{ // assert(pc); // // if (pc->sz == MAX) // { // printf("通訊錄已滿,無法添加數(shù)據(jù)\n"); // return; // } // // //增加人的信息 // printf("請輸入名字:>"); // scanf("%s", pc->data[pc->sz].name); // printf("請輸入性別:>"); // scanf("%s", pc->data[pc->sz].sex); // printf("請輸入年齡:>"); // scanf("%d", &(pc->data[pc->sz].age)); // printf("請輸入電話:>"); // scanf("%s", pc->data[pc->sz].tele); // printf("請輸入地址:>"); // scanf("%s", pc->data[pc->sz].addr); // // pc->sz++; // printf("成功增加聯(lián)系人\n"); //} static int check_capacity(struct Contact* pc) { if (pc->sz == pc->capacity) { //增加容量 struct PeoInfo* ptr = (struct PeoInfo*)realloc(pc->data, (pc->capacity + INC_SZ) * sizeof(struct PeoInfo)); if (ptr != NULL) { pc->data = ptr; pc->capacity += INC_SZ; printf("增容成功\n"); return 1; } else { perror("AddContact()"); return 0; } } else return 1; } //動態(tài)增長的版本 void AddContact(struct Contact* pc) { assert(pc); if (0 == check_capacity(pc)) { return; } //增加人的信息 printf("請輸入名字:>"); scanf("%s", pc->data[pc->sz].name); printf("請輸入性別:>"); scanf("%s", pc->data[pc->sz].sex); printf("請輸入年齡:>"); scanf("%d", &(pc->data[pc->sz].age)); printf("請輸入電話:>"); scanf("%s", pc->data[pc->sz].tele); printf("請輸入地址:>"); scanf("%s", pc->data[pc->sz].addr); pc->sz++; printf("成功增加聯(lián)系人\n"); } void ShowContact(const struct Contact* pc) { int i = 0; printf("%-20s\t%-5s\t%-5s\t%-12s\t%-30s\n", "姓名", "性別", "年齡", "電話", "地址"); for (i = 0; i < pc->sz; i++) { printf("%-20s\t%-5s\t%-5d\t%-12s\t%-30s\n", pc->data[i].name, pc->data[i].sex, pc->data[i].age, pc->data[i].tele, pc->data[i].addr); } } static int FindByName(const struct Contact* pc, char name[]) { int i = 0; for (i = 0; i < pc->sz; i++) { if (0 == strcmp(pc->data[i].name, name)) { return i; } } return -1; } void DelContact(struct Contact* pc) { char name[MAX_NAME]; printf("請輸入要刪除人的名字:>"); scanf("%s", name); //查找一下指定的人是否存在 int ret = FindByName(pc, name); if (ret == -1) printf("要刪除的人不存在\n"); else { //刪除 int j = 0; for (j = ret; j < pc->sz - 1; j++) { pc->data[j] = pc->data[j + 1]; } pc->sz--; printf("成功刪除指定聯(lián)系人\n"); } } void SearchContact(const struct Contact* pc) { char name[MAX_NAME]; printf("請輸入要查找的人的名字:>"); scanf("%s", name); //查找一下指定的人是否存在 int ret = FindByName(pc, name); if (ret == -1) printf("要查找的人不存在\n"); else { printf("%-20s\t%-5s\t%-5s\t%-12s\t%-30s\n", "姓名", "性別", "年齡", "電話", "地址"); printf("%-20s\t%-5s\t%-5d\t%-12s\t%-30s\n", pc->data[ret].name, pc->data[ret].sex, pc->data[ret].age, pc->data[ret].tele, pc->data[ret].addr); } } void ModifyContact(struct Contact* pc) { printf("請輸入要修改人的名字:>"); char name[MAX_NAME]; scanf("%s", name); int ret = FindByName(pc, name); if (ret == -1) printf("要修改的人不存在\n"); else { printf("請輸入名字:>"); scanf("%s", pc->data[ret].name); printf("請輸入性別:>"); scanf("%s", pc->data[ret].sex); printf("請輸入年齡:>"); scanf("%d", &(pc->data[ret].age)); printf("請輸入電話:>"); scanf("%s", pc->data[ret].tele); printf("請輸入地址:>"); scanf("%s", pc->data[ret].addr); printf("修改成功\n"); } } //int CmpByAge(const void* e1, const void* e2) //{ // return ((struct PeoInfo*)e1)->age - ((struct PeoInfo*)e2)->age; //} // 按照年齡來排序 //void SortContact(struct Contact* pc) //{ // qsort(pc->data, pc->sz, sizeof(struct PeoInfo), CmpByAge); //} int CmpByName(const void* e1, const void* e2) { return strcmp(((struct PeoInfo*)e1)->name, ((struct PeoInfo*)e2)->name); } //按照年齡來排序 void SortContact(struct Contact* pc) { qsort(pc->data, pc->sz, sizeof(struct PeoInfo), CmpByName); } void SaveContact(struct Contact* pc) { //打開文件 FILE* pfW = fopen("data.txt", "wb"); if (pfW == NULL) { perror("SaveContact::fopen"); return; } //寫文件 int i = 0; for (i = 0; i < pc->sz; i++) { fwrite(pc->data+i, sizeof(struct PeoInfo), 1, pfW); } //關(guān)閉文件 fclose(pfW); pfW = NULL; }
部分函數(shù)還需要添加頭文件。
對于這個通訊錄寫入有部分細節(jié)需要注意比如動態(tài)開辟后,空間是否開辟成功,空間使用后需要關(guān)閉,并將指針NULL。文件操作類似。這個通訊錄實現(xiàn)后最后也是保存在文件中后期數(shù)據(jù)較大了,讀寫較慢耗時。而且數(shù)據(jù)也不安全,文件保存容易被修改和丟失。后期可以使用數(shù)據(jù)庫實現(xiàn)數(shù)據(jù)保存。
以上就是基于C++實現(xiàn)三種不同版本的通訊錄的詳細內(nèi)容,更多關(guān)于C++通訊錄的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
QT實現(xiàn)QML側(cè)邊導(dǎo)航欄的最簡方法
本文主要介紹了QT實現(xiàn)QML側(cè)邊導(dǎo)航欄的最簡方法,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-06-06Visual C++ 常用數(shù)據(jù)類型轉(zhuǎn)換方法詳解
本文純粹是總結(jié)一下有關(guān)類型轉(zhuǎn)換的貼子,需要的朋友可以參考下2017-06-06Visual Studio 2019安裝、測試創(chuàng)建c語言項目(圖文教程)
這篇文章主要介紹了Visual Studio 2019安裝、測試創(chuàng)建c語言項目,Visual Studio 2019是完全免費的,而且安裝比較簡單,現(xiàn)在把安裝步驟分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2020-03-03