C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)單的通訊錄管理系統(tǒng)
本文實(shí)例為大家分享了C語(yǔ)言實(shí)現(xiàn)通訊錄管理系統(tǒng)的具體代碼,供大家參考,具體內(nèi)容如下
要實(shí)現(xiàn)一個(gè)通訊錄管理系統(tǒng),需要用到結(jié)構(gòu)體、指針、文件操作、動(dòng)態(tài)管理等內(nèi)容。
效果展示:
實(shí)現(xiàn)思路
通訊錄中的聯(lián)系人包括姓名、年齡、性別、電話、住址,因此可以定義一個(gè)結(jié)構(gòu)體PeoInfo來(lái)存儲(chǔ)這些信息。
同時(shí),由于通訊錄需要記錄當(dāng)前的大小,以此來(lái)方便我們對(duì)通訊錄realloc進(jìn)行擴(kuò)容,所以需要定義通訊錄結(jié)構(gòu)體Contact來(lái)保存這些信息,其中該結(jié)構(gòu)體中可以嵌套一個(gè)PeoInfo類型的指針。
當(dāng)定義完結(jié)構(gòu)體以后,就可以對(duì)定義的結(jié)構(gòu)體進(jìn)行增刪查改,其中可以先使用malloc對(duì)通訊錄結(jié)構(gòu)體進(jìn)行初始化,然后再完成添加、刪除、查找、修改、保存、排序、清空等一系列函數(shù)。
在保存時(shí),需要用到文件指針將數(shù)據(jù)保存到文件中,因此在一開始當(dāng)前目錄下需要一個(gè)相應(yīng)的文件。
同時(shí)在初始化時(shí),也要將文件中的數(shù)據(jù)讀取到我們的結(jié)構(gòu)體指針指向的內(nèi)容中。
在這里使用contact.txt文件來(lái)保存信息:
為了方便,我們將函數(shù)聲明,函數(shù)實(shí)現(xiàn),以及游戲的實(shí)現(xiàn)放到三個(gè)不同文件里:
contact.h內(nèi)容
#pragma once #include<stdio.h> #include<string.h> #include<stdlib.h> #include<errno.h> #define MAX_NAME 10//名字的大小 #define MAX_SEX 5//性別大小 #define MAX_TELE 15//電話大小 #define MAX_ADDR 30//地址大小 #define DEFAULT_SZ 3 //通訊錄默認(rèn)的大小 enum Option { ?? ?EXIT, ?? ?ADD, ?? ?DEL, ?? ?SEARCH, ?? ?MODIFY, ?? ?SHOW, ?? ?SORT, ?? ?SAVE, ?? ?CLEAR }; struct PeoInfo { ?? ?char name[MAX_NAME]; ?? ?int age; ?? ?char sex[MAX_SEX]; ?? ?char tele[MAX_TELE]; ?? ?char addr[MAX_ADDR]; }; //通訊錄類型 struct Contact { ?? ?struct PeoInfo* data;//存放信息 ?? ?int size;//記錄當(dāng)前已經(jīng)有的元素個(gè)數(shù) ?? ?int capacity;//當(dāng)前通訊錄的最大容量 }; //初始化通訊錄 void InitContact(struct Contact* ps); //增加通訊錄內(nèi)容 void AddContact(struct Contact* ps); //打印通訊錄信息 void ShowContact(const struct Contact* ps); //刪除通訊錄信息 void DelContact(struct Contact* ps); //查找通訊錄信息 void SearchContact(const struct Contact* ps); //修改指定聯(lián)系人 void ModifyContact(struct Contact* ps); //按姓名排序 void SortContact(struct Contact* ps); //釋放動(dòng)態(tài)開辟的內(nèi)存 void DestroyContact(struct Contact* ps); //保存通訊錄 void SaveContact(struct Contact* ps); //加載文件中的信息到通訊錄 void LoadContact(struct Contact* ps); //清空通訊錄 void ClearContact(struct Contact* ps);
這個(gè)文件中主要包括結(jié)構(gòu)體的創(chuàng)建,以及各種函數(shù)的聲明。
contact.c內(nèi)容
#include"contact.h" void InitContact(struct Contact* ps) { ?? ?ps ->data =(struct PeoInfo*) malloc(DEFAULT_SZ * sizeof(struct PeoInfo)); ?? ?if (ps->data == NULL) ?? ?{ ?? ??? ?printf("空間開辟失敗"); ?? ??? ?return; ?? ?} ?? ?ps->size = 0; ?? ?ps->capacity = DEFAULT_SZ; ?? ?//把文件中存放的信息加載到通訊錄中 ?? ?LoadContact(ps); } void CheckCapacity(struct Contact* ps) { ?? ?if (ps->size == ps->capacity) ?? ?{ ?? ??? ?struct PeoInfo* ptr = (struct PeoInfo*)realloc(ps->data, (ps->capacity + 5) * sizeof(struct PeoInfo)); ?? ??? ?if (ptr != NULL) ?? ??? ?{ ?? ??? ??? ?ps->data = ptr; ?? ??? ??? ?ps->capacity += 5; ?? ??? ?} ?? ?} } void LoadContact(struct Contact* ps) { ?? ?struct PeoInfo tmp = { 0 }; ?? ?FILE* pfRead = fopen("contact.txt", "rb"); ?? ?if (pfRead == NULL) ?? ?{ ?? ??? ?printf("文件不存在:%s\n", strerror(errno)); ?? ??? ?return; ?? ?} ?? ?//讀取文件 ?? ?while (fread(&tmp, sizeof(struct PeoInfo), 1, pfRead)) ?? ?{ ?? ??? ?CheckCapacity(ps); ?? ??? ?ps->data[ps->size] = tmp; ?? ??? ?ps->size++; ?? ?} ?? ?fclose(pfRead); ?? ?pfRead = NULL; } void AddContact(struct Contact* ps) { ?? ?//檢測(cè)當(dāng)前通訊錄的容量,如果滿了則增容 ?? ?CheckCapacity(ps); ?? ?printf("請(qǐng)輸入名字->"); ?? ?scanf("%s", ps->data[ps->size].name); ?? ?printf("請(qǐng)輸入年齡->"); ?? ?scanf("%d", &(ps->data[ps->size].age)); ?? ?printf("請(qǐng)輸入性別->"); ?? ?scanf("%s", ps->data[ps->size].sex); ?? ?printf("請(qǐng)輸入電話->"); ?? ?scanf("%s", ps->data[ps->size].tele); ?? ?printf("請(qǐng)輸入地址->"); ?? ?scanf("%s", ps->data[ps->size].addr); ?? ? ?? ?ps->size++; ?? ?printf("添加成功\n"); ?? ? } void ShowContact(const struct Contact* ps) { ?? ?if (ps->size == 0) ?? ?{ ?? ??? ?printf("通訊錄為空\(chéng)n"); ?? ?} ?? ?else ?? ?{ ?? ??? ?int i = 0; ?? ??? ?printf("%-10s\t%-4s\t%-5s\t%-12s\t%-20s\n", "名字", "年齡", "性別", "電話", "地址"); ?? ??? ?{ ?? ??? ??? ?for (i = 0; i < ps->size; i++)//打印每個(gè)通訊錄元素 ?? ??? ??? ?{ ?? ??? ??? ??? ?printf("%-10s\t%-4d\t%-5s\t%-12s\t%-20s\n",? ?? ??? ??? ??? ??? ?ps->data[i].name, ps->data[i].age, ps->data[i].sex,? ?? ??? ??? ??? ??? ?ps->data[i].tele, ps->data[i].addr); ?? ??? ??? ?} ?? ??? ?} ?? ?} } //查找聯(lián)系人位置 int FindByName(const struct Contact* ps, char name[MAX_NAME]) { ?? ?//查找要?jiǎng)h除人的位置 ?? ?int i = 0; ?? ?for (i = 0; i < ps->size; i++) ?? ?{ ?? ??? ?if (0 == strcmp(ps->data[i].name, name)) ?? ??? ?{ ?? ??? ??? ?return i;//找到返回下標(biāo) ?? ??? ?} ?? ?} ?? ?return -1;//找不到返回-1 } void DelContact(struct Contact* ps) { ?? ?char name[MAX_NAME]; ?? ?printf("請(qǐng)輸入要?jiǎng)h除人的名字:->"); ?? ?scanf("%s", name); ?? ?//查找要?jiǎng)h除人的位置 ?? ?int pos=FindByName(ps, name);//找到返回名字所在的下標(biāo),找不到返回-1 ?? ? ?? ?if (pos==-1) ?? ?{ ?? ??? ?printf("聯(lián)系人不存在\n"); ?? ?} ?? ?else ?? ?{ ?? ??? ?//刪除 ?? ??? ?int j = 0; ?? ??? ?for (j = pos; j < ps->size-1; j++) ?? ??? ?{ ?? ??? ??? ?ps->data[j] = ps->data[j + 1]; ?? ??? ?} ?? ??? ?ps->size--; ?? ??? ?printf("刪除成功\n"); ?? ?} } void SearchContact(const struct Contact* ps) { ?? ?char name[MAX_NAME]; ?? ?printf("請(qǐng)輸入要查找人的名字:->"); ?? ?scanf("%s", name); ?? ?int pos = FindByName(ps, name);//找到返回名字所在的下標(biāo),找不到返回-1 ?? ?if (pos == -1) ?? ?{ ?? ??? ?printf("聯(lián)系人不存在\n"); ?? ?} ?? ?else ?? ?{ ?? ??? ?printf("%-10s\t%-4s\t%-5s\t%-12s\t%-20s\n", "名字", "年齡", "性別", "電話", "地址");?? ??? ? ?? ??? ?printf("%-10s\t%-4d\t%-5s\t%-12s\t%-20s\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[MAX_NAME]; ?? ?printf("請(qǐng)輸入要修改人的名字:->"); ?? ?scanf("%s", name); ?? ?int pos = FindByName(ps, name);//找到返回名字所在的下標(biāo),找不到返回-1 ?? ?if (pos == -1) ?? ?{ ?? ??? ?printf("聯(lián)系人不存在\n"); ?? ?} ?? ?else ?? ?{ ?? ??? ?printf("請(qǐng)輸入名字->"); ?? ??? ?scanf("%s", ps->data[pos].name); ?? ??? ?printf("請(qǐng)輸入年齡->"); ?? ??? ?scanf("%d", &(ps->data[pos].age)); ?? ??? ?printf("請(qǐng)輸入性別->"); ?? ??? ?scanf("%s", ps->data[pos].sex); ?? ??? ?printf("請(qǐng)輸入電話->"); ?? ??? ?scanf("%s", ps->data[pos].tele); ?? ??? ?printf("請(qǐng)輸入地址->"); ?? ??? ?scanf("%s", ps->data[pos].addr); ?? ??? ?printf("修改完成\n"); ?? ?} } void SortContact(struct Contact* ps) { ?? ?for (int i = 0; i < ps->size - 1; ++i) ?? ?{ ?? ??? ?for (int j = 0; j < ps->size - i - 1; ++j) ?? ??? ?{ ?? ??? ??? ?if (strcmp(ps->data[j].name, ps->data[j + 1].name) > 0) ?? ??? ??? ?{ ?? ??? ??? ??? ?struct PeoInfo tmp = ps->data[j]; ?? ??? ??? ??? ?ps->data[j] = ps->data[j + 1]; ?? ??? ??? ??? ?ps->data[j + 1] = tmp; ?? ??? ??? ?} ?? ??? ?} ?? ?} ?? ?printf("按姓名排序成功\n"); } //釋放動(dòng)態(tài)開辟的空間 void DestroyContact(struct Contact* ps) { ?? ?free(ps->data); ?? ?ps->data=NULL; } void SaveContact(struct Contact* ps) { ?? ?FILE* pfWrite = fopen("contact.txt", "wb"); ?? ?if (pfWrite == NULL) ?? ?{ ?? ??? ?printf("%s\n", strerror(errno)); ?? ??? ?return; ?? ?} ?? ?//將通訊錄的信息寫入文件 ?? ?int i = 0; ?? ?for (i = 0; i < ps->size; i++) ?? ?{ ?? ??? ?fwrite(&(ps->data[i]), sizeof(struct PeoInfo), 1, pfWrite); ?? ?} ?? ?printf("保存成功\n"); ?? ?fclose(pfWrite); ?? ?pfWrite = NULL; } void ClearContact(struct Contact* ps) { ?? ?printf("確定要清空通訊錄嗎?<Y/N> :>"); ?? ?char ch; ?? ?getchar();//清空緩存區(qū)里面的\n ?? ?scanf("%c", &ch); ?? ?if (ch == 'Y' || ch == 'y') ?? ?{ ?? ??? ?ps->size = 0; ?? ??? ?memset(ps->data, 0, sizeof(ps->data)); ?? ??? ?printf("清空成功\n"); ?? ?} ?? ?else ?? ?{ ?? ??? ?printf("取消清空\(chéng)n"); ?? ?} ?? ? }
在這個(gè)文件中我們將聲明的函數(shù)進(jìn)行了定義,用到的方法都比較簡(jiǎn)單。
test.c內(nèi)容
#include"contact.h" void menu() { ?? ?printf("**************************************************\n"); ?? ?printf("****1.添加聯(lián)系人 ? ? ? ?2.刪除聯(lián)系人**************\n"); ?? ?printf("****3.查找聯(lián)系人 ? ? ? ?4.修改聯(lián)系人*************\n"); ?? ?printf("****5.展示所有聯(lián)系人 ? ?6.按姓名排序聯(lián)系人********\n"); ?? ?printf("****7.保存通訊錄 ? ? ? ?8.清空通訊錄*************\n"); ?? ?printf("**************0.退出通訊錄************************\n"); ?? ?printf("**************************************************\n"); } int main() { ?? ?int input = 0; ?? ?//創(chuàng)建通訊錄 ?? ?int size = 0; ?? ?struct Contact con;//con是通訊錄 ?? ?//初始化通訊錄 ?? ?InitContact(&con); ?? ?do ?? ?{ ?? ??? ?menu(); ?? ??? ?printf("請(qǐng)選擇->"); ?? ??? ?scanf("%d", &input); ?? ??? ?switch (input) ?? ??? ?{ ?? ??? ?case ADD: ?? ??? ??? ?AddContact(&con); ?? ??? ??? ?system("pause"); ?? ??? ??? ?system("cls"); ?? ??? ??? ?break; ?? ??? ?case DEL: ?? ??? ??? ?DelContact(&con); ?? ??? ??? ?system("pause"); ?? ??? ??? ?system("cls"); ?? ??? ??? ?break; ?? ??? ?case SEARCH: ?? ??? ??? ?SearchContact(&con); ?? ??? ??? ?system("pause"); ?? ??? ??? ?system("cls"); ?? ??? ??? ?break; ?? ??? ?case MODIFY: ?? ??? ??? ?ModifyContact(&con); ?? ??? ??? ?system("pause"); ?? ??? ??? ?system("cls"); ?? ??? ??? ?break; ?? ??? ?case SHOW: ?? ??? ??? ?ShowContact(&con); ?? ??? ??? ?system("pause"); ?? ??? ??? ?system("cls"); ?? ??? ??? ?break; ?? ??? ?case SORT: ?? ??? ??? ?SortContact(&con); ?? ??? ??? ?system("pause"); ?? ??? ??? ?system("cls"); ?? ??? ??? ?break; ?? ??? ?case SAVE: ?? ??? ??? ?SaveContact(&con); ?? ??? ??? ?system("pause"); ?? ??? ??? ?system("cls"); ?? ??? ??? ?break; ?? ??? ?case CLEAR: ?? ??? ??? ?ClearContact(&con); ?? ??? ??? ?system("pause"); ?? ??? ??? ?system("cls"); ?? ??? ??? ?break; ?? ??? ?case EXIT: ?? ??? ??? ?SaveContact(&con); ?? ??? ??? ?//釋放動(dòng)態(tài)開辟的內(nèi)存 ?? ??? ??? ?DestroyContact(&con); ?? ??? ??? ?break; ?? ??? ?default: ?? ??? ??? ?printf("選擇錯(cuò)誤\n"); ?? ??? ??? ?break; ?? ??? ?} ?? ?} while (input); }
在這個(gè)文件中將對(duì)菜單進(jìn)行打印,同時(shí)進(jìn)行函數(shù)的調(diào)用。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- C語(yǔ)言通訊錄管理系統(tǒng)完整版
- C語(yǔ)言通訊錄管理系統(tǒng)課程設(shè)計(jì)
- C語(yǔ)言實(shí)現(xiàn)個(gè)人通訊錄管理系統(tǒng)
- C語(yǔ)言實(shí)現(xiàn)通訊錄管理系統(tǒng)
- 基于C語(yǔ)言實(shí)現(xiàn)個(gè)人通訊錄管理系統(tǒng)
- C語(yǔ)言通訊錄管理系統(tǒng)完整代碼
- C語(yǔ)言單鏈表實(shí)現(xiàn)通訊錄管理系統(tǒng)
- C語(yǔ)言代碼實(shí)現(xiàn)通訊錄管理系統(tǒng)
- C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)單通訊錄管理系統(tǒng)
- c語(yǔ)言實(shí)現(xiàn)通訊錄管理系統(tǒng)詳細(xì)實(shí)例
相關(guān)文章
C++實(shí)現(xiàn)基于時(shí)序公平的讀寫鎖詳解
讀寫鎖與普通的互斥鎖的區(qū)別在于有兩種上鎖方式:讀鎖和寫鎖,不用的用戶對(duì)同一個(gè)讀寫鎖獲取讀鎖是非互斥的,其他情況則是互斥的,本文小編將給大家詳細(xì)介紹C++實(shí)現(xiàn)基于時(shí)序公平的讀寫鎖,需要的朋友可以參考下2023-10-10利用C語(yǔ)言實(shí)現(xiàn)http服務(wù)器(Linux)
本文將利用C語(yǔ)言實(shí)現(xiàn)一個(gè)輕量級(jí)的http服務(wù)器,使用Reactor模式,即主線程只負(fù)責(zé)監(jiān)聽文件描述符上是否有事件發(fā)生,有的話立即將該事件通知工作線程,感興趣的可以了解一下2022-07-07c語(yǔ)言中十進(jìn)制轉(zhuǎn)二進(jìn)制顯示小工具的實(shí)現(xiàn)代碼
本篇文章是對(duì)c語(yǔ)言中十進(jìn)制轉(zhuǎn)二進(jìn)制顯示小工具的實(shí)現(xiàn)代碼進(jìn)行了詳細(xì)的分析的介紹,需要的朋友參考下2013-05-05C++實(shí)現(xiàn)LeetCode(76.最小窗口子串)
這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode(76.最小窗口子串),本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-07-07Qt物聯(lián)網(wǎng)管理平臺(tái)之實(shí)現(xiàn)自動(dòng)清理早期數(shù)據(jù)功能
隨著時(shí)間的增加,存儲(chǔ)的歷史記錄也在不斷增加,如果設(shè)備數(shù)量很多,存儲(chǔ)間隔很短,不用多久,數(shù)據(jù)庫(kù)中的記錄就非常多,至少是百萬(wàn)級(jí)別起步,而且有些用戶還是需要存儲(chǔ)每一次的采集的數(shù)據(jù)。本文將利用Qt實(shí)現(xiàn)自動(dòng)清理早期數(shù)據(jù),需要的可以參考一下2022-07-07C++數(shù)據(jù)結(jié)構(gòu)之list詳解
list是一種序列式容器。list容器完成的功能實(shí)際上和數(shù)據(jù)結(jié)構(gòu)中的雙向鏈表是極其相似的,list中的數(shù)據(jù)元素是通過(guò)鏈表指針串連成邏輯意義上的線性表,也就是list也具有鏈表的主要優(yōu)點(diǎn),即:在鏈表的任一位置進(jìn)行元素的插入、刪除操作都是快速的2021-11-11