【數據結構】2.順序表實現通訊錄

文章目錄

  • 一、通訊錄的要求
  • 二、通訊錄的具體實現
    • 0、 準備工作
    • 1、通訊錄的初始化
    • 2、通訊錄的銷毀
    • 3、通訊錄的展示
    • 4、通訊錄添加數據
    • 5、通訊錄刪除數據
    • 6、通訊錄的查找
    • 7、通訊錄的修改
    • 8、保存通訊錄數據到文件
    • 9、讀取文件內容到通訊錄
  • 三、 通訊錄的完整實現

一、通訊錄的要求

通訊錄所能實現的功能要求如下:
1)?少能夠存儲100個?的通訊信息
2)能夠保存??信息:名字、性別、年齡、電話、地址等
3)增加聯系?
4)刪除指定聯系?
5)查找指定聯系?
6)修改指定聯系?
7)顯?聯系?信息

二、通訊錄的具體實現

0、 準備工作

:本文所有的SeqList文件均在上文講解過,如果有不懂的可以點擊藍色字體查看上文。

通訊錄的實現是基于動態順序表實現的,可以理解為在動態順序表上面套了一層殼子叫做通訊錄,里面的核心還是動態順序表。

由此圖可以理解為原來動態順序表的一個元素,現在變成了一個結構體(包含了聯系人的信息)。

由于是在動態順序表的基礎上實現的,所以還需要包含前文所寫的SeqList.h和SeqList.c文件,因此要實現通訊錄需要包含5個文件:
SeqList.h
SeqList.c:
Contact.h:通訊錄函數的聲明,結構體構造,宏定義。
Contact.c:通訊錄函數的實現。
test.c:通訊錄函數的測試

如果要實現通訊錄,那我們首先需要定義一個聯系人的結構體,包含聯系人的各種信息。

即:

這些信息僅做參考,還可以根據需求自己定義一些相關信息。

結構體在通訊錄的頭文件Contact.h中定義:

typedef struct PersonInfo
{char name[10];//姓名char sex[10];//性別int age;//年齡char tel[20];//電話char addr[100];//地址
}Peo

但是為了便于維護,我們可以將數組的最大值用宏定義來替代,提高代碼的便利性。
即:

#define NAME_MAX 10
#define SEX_MAX 10
#define TEL_MAX 20
#define ADDR_MAX 100typedef struct PersonInfo
{char name[NAME_MAX];//姓名char sex[SEX_MAX];//性別int age;///年齡char tel[TEL_MAX];//電話char addr[ADDR_MAX];//地址
}PeoInfo;

之前在順序表中,一個元素的類型一般是int類型,現在我們用結構體替代原來的元素,元素類型應該變成結構體類型PeoInfo。
因此需要將SeqList.h文件中的:

typedef int SLDataType;

改為:

typedef PeoInfo SLDataType;

而在SeqList.h文件中引用Contact.h文件中的內容,需要在SeqList.h中添加#include"Contact.h"

由于我們實質上是對順序表進行操作,所以需要對在Contact.h中為順序表重新起個名字叫做通訊錄:

typedef struct SeqList Contact;

接下來就進入正式部分,首先對需要實現的通訊錄相關的方法在Conatct.h中進行聲明:

//通訊錄的初始化
void ContactInit(Contact* con);//通訊錄的銷毀
void ContactDestroy(Contact* con);//通訊錄的展示
void ContactShow(Contact* con);//通訊錄添加數據
void ContactAdd(Contact* con);//通訊錄刪除數據
void ContactDel(Contact* con);//通訊錄的查找
void ContactFind(Contact* con);//通訊錄的修改
void ContactModify(Contact* con);//保存通訊錄數據到文件
void SaveContact(Contact* con);//讀取文件內容到通訊錄
void LoadContact(Contact* con);

接下來再在Contact.c文件中來實現方法,首要需要引用頭文件:#include"Contact.h",同時實現的部分方法是直接使用的順序表的方法,因此還需要引用順序表:#include"SeqList.h"
現在完事具備,可以來實現方法了。

1、通訊錄的初始化

通訊錄的初始化:直接調用順序表的初始化。

void ContactInit(Contact* con)
{//調用順序表的初始化SLInit(con);
}

在test.c中進行測試:

int main()
{Contact con;ContactInit(&con);return 0;
}

通過測試發現通訊錄初始化成功!

2、通訊錄的銷毀

通訊錄的銷毀:同樣直接調用順序表的銷毀即可。

void ContactDestroy(Contact* con)
{//調用順序表的銷毀SLDestroy(con);
}

再進行測試:

int main()
{Contact con;ContactInit(&con);ContactDestroy(&con);return 0;
}

3、通訊錄的展示

通訊錄的展示:先打印表頭,再依次打印通訊錄中每一個結構體里的五個通訊錄信息。

void ContactShow(Contact* con)
{//打印表頭printf("%-10s %-4s %-4s %-11s %-20s\n", "姓名", "性別", "年齡", "電話", "地址");//for循環依次打印通訊錄中每一個(元素)結構體里的5個通訊錄信息for (int i = 0; i < con->size; i++){printf("%-10s %-4s %-4d %-11s %-20s\n",con->arr[i].name,con->arr[i].sex,con->arr[i].age,con->arr[i].tel,con->arr[i].addr);}
}

:-號表示左對齊,10表示輸出的數據占10個字符。

再進行測試:

int main()
{Contact con;ContactInit(&con);ContactShow(&con);return 0;
}

通過測試發現通訊錄展示成功!

4、通訊錄添加數據

通訊錄添加數據:輸入一個元素的通訊錄信息,再尾插到通訊錄(順序表)中。

void ContactAdd(Contact* con)
{//輸入一個元素(結構體)的通訊錄信息PeoInfo info;printf("請輸入要添加的聯系人姓名:");scanf("%s", info.name);//數組不用取地址&printf("請輸入要添加的聯系人性別:");scanf("%s",info.sex);printf("請輸入要添加的聯系人年齡:");scanf("%d", &info.age);printf("請輸入要添加的聯系人電話:");scanf("%s", info.tel);printf("請輸入要添加的聯系人地址:");scanf("%s", info.addr);//將其尾插到通訊錄(順序表)中SLPushBack(con, info);printf("聯系人數據添加成功!\n");
}

再進行測試:

int main()
{Contact con;ContactInit(&con);ContactAdd(&con);ContactShow(&con);return 0;
}

通過測試發現通訊錄添加數據成功!

5、通訊錄刪除數據

在進行刪除、查找等操作的時候,我們需要通過姓名這個唯一性元素來得到其整個信息,然后再進行操作。
根據姓名查找:遍歷通訊錄,找到返回下標,否則返回-1

int FindByName(Contact* con, char Name[])
{//遍歷通訊錄,查看通訊錄每一個元素中的姓名是否與傳入的姓名相同for (int i = 0; i < con->size; i++){if (0 == strcmp(con->arr[i].name, Name)){//返回下標return i;}}//找不到return -1;
}

接下來再進行通訊錄的刪除:輸入姓名,找到下標,調用順序表指定位置刪除,刪除下標對應的數據。

void ContactDel(Contact* con)
{//輸入要刪除的姓名char Name[NAME_MAX];printf("請輸入你要刪除的聯系人姓名:");scanf("%s", Name);//找到下標int find = FindByName(con, Name);if (find < 0){printf("你要刪除的聯系人數據不存在!\n");}//調用順序表指定位置的刪除  刪除下標對應的數據SLErase(con, find);printf("聯系人數據刪除成功!\n");
}

再進行測試:

int main()
{Contact con;ContactInit(&con);ContactAdd(&con);ContactShow(&con);ContactDel(&con);ContactShow(&con);return 0;
}

通過測試發現通訊錄數據刪除成功!

6、通訊錄的查找

通訊錄的查找:輸入姓名,找到下標,打印下標對應的數據。

void ContactFind(Contact* con)
{//輸入要查找的姓名char Name[NAME_MAX];printf("請輸入你要查找的聯系人姓名:");scanf("%s", Name);//找到下標int find = FindByName(con, Name);if (find < 0){printf("你要查找的聯系人數據不存在!\n");}//打印下標對應的數據printf("%-10s %-4s %-4s %-11s %-20s\n", "姓名", "性別", "年齡", "電話", "地址");printf("%-10s %-4s %-4d %-11s %-20s\n",con->arr[find].name,con->arr[find].sex,con->arr[find].age,con->arr[find].tel,con->arr[find].addr );
}

再進行測試:

int main()
{Contact con;ContactInit(&con);ContactAdd(&con);ContactShow(&con);ContactFind(&con);return 0;
}

通過測試發現通訊錄查找成功!

7、通訊錄的修改

通訊錄的修改:輸入姓名,找到下標,修改下標對應的數據。

void ContactModify(Contact* con)
{//輸入姓名char Name[NAME_MAX];printf("請輸入你要修改的聯系人姓名:");scanf("%s", Name);//找到下標int find = FindByName(con, Name);if (find < 0){printf("你要修改的聯系人數據不存在!\n");}//修改下標對應的數據printf("請輸入新的聯系人姓名:");scanf("%s", con->arr[find].name);printf("請輸入新的聯系人性別:");scanf("%s", con->arr[find].sex);printf("請輸入新的聯系人年齡:");scanf("%d", &con->arr[find].age);printf("請輸入新的聯系人電話:");scanf("%s", con->arr[find].tel);printf("請輸入新的聯系人地址:");scanf("%s", con->arr[find].addr);printf("聯系人數據修改成功!\n");
}

再進行測試:

int main()
{Contact con;ContactInit(&con);ContactAdd(&con);ContactShow(&con);ContactModify(&con);ContactShow(&con);return 0;
}

經過測試通訊錄的修改成功!

8、保存通訊錄數據到文件

保存數據到文件:打開文件,聯系人數據寫入文件,關閉文件。

void SaveContact(Contact* con)
{//打開文件FILE* pf = fopen("Contact.txt", "ab");//如果打開失敗{if (pf == NULL){perror("fopen fail");}}//將聯系人數據寫入文件for (int i = 0; i < con->size; i++){fwrite(con->arr + i, sizeof(PeoInfo), 1, pf);}printf("通訊錄數據保存成功!\n");//關閉文件fclose(pf);
}

再進行測試:

int main()
{Contact con;ContactInit(&con);ContactAdd(&con);ContactShow(&con);SaveContact(&con);return 0;
}

同時我們可以點擊添加源文件,添加現有項,將Contact.txt文件添加進來,再將txt文件的打開方式設置為二進制編輯器。‘’
就可以在Contact.txt文件中看到;

說明數據已經以二進制的形式保存在文件中了。

9、讀取文件內容到通訊錄

讀取文件內容到通訊錄:打開文件,讀取文件,尾插到通訊錄中,關閉文件。

void LoadContact(Contact* con)
{//打開文件FILE* pf=fopen("Contact.txt","rb");//如果打開失敗if (pf == NULL){perror("fopen fail");}//讀取文件數據PeoInfo info;while (fread(&info, sizeof(PeoInfo), 1, pf)){//文件數據尾插到通訊錄中SLPushBack(con, info);}//關閉文件fclose(pf);
}

再進行測試:

int main()
{Contact con;ContactInit(&con);ContactShow(&con);LoadContact(&con);ContactShow(&con);return 0;
}

可以觀察到,一開始原本沒有數據,但是在我們讀取文件到通訊錄之后,就有了數據,說明讀取文件內容到通訊錄成功了!

三、 通訊錄的完整實現

在我們實現了通訊錄的所有方法之后,我們可以將其集合起來做成完整的通訊錄。
再在test.c中來實現這個完整的程序:

#define _CRT_SECURE_NO_WARNINGS
#include"SeqList.h"//打印通訊錄界面
void menu()
{printf("**************      通訊錄    **************\n");printf("*******  1.增加聯系人   2.刪除聯系人  ******\n");printf("*******  3.修改聯系人   4.查找聯系人  ******\n");printf("*******  5.展示聯系人   6.保存聯系人  ******\n");printf("*******  7.導入聯系人   0.退出        ******\n");printf("********************************************\n");
}int main()
{//通訊錄初始化int input = -1;Contact con;ContactInit(&con);//用do while先執行一次循環,輸入0循環結束do{menu();//輸入序號printf("請選擇你要執行的操作:");scanf("%d", &input);//根據輸入的序號執行對應的操作 switch (input){case 1:ContactAdd(&con);break;case 2:ContactDel(&con);break;case 3:ContactModify(&con);break;case 4:ContactFind(&con);break;case 5:ContactShow(&con);break;case 6:SaveContact(&con);break;case 7:LoadContact(&con);break;case 0:printf("退出通訊錄...\n");break;default:printf("輸入錯誤,請重新選擇你的操作:\n");break;}	} while (input != 0);//通訊錄銷毀ContactDestroy(&con);return 0;
}

效果如下:

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/76512.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/76512.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/76512.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

程序化廣告行業(79/89):技術革新與行業發展脈絡梳理

程序化廣告行業&#xff08;79/89&#xff09;&#xff1a;技術革新與行業發展脈絡梳理 大家好&#xff01;一直以來&#xff0c;我都熱衷于在技術領域不斷探索&#xff0c;也深知知識共享對于進步的重要性。寫這篇博客&#xff0c;就是希望能和大家一起深入研究程序化廣告行業…

【C++游戲引擎開發】第9篇:數學計算庫GLM(線性代數)、CGAL(幾何計算)的安裝與使用指南

寫在前面 兩天都沒手搓實現可用的凸包生成算法相關的代碼&#xff0c;自覺無法手搓相關數學庫&#xff0c;遂改為使用成熟數學庫。 一、GLM庫安裝與介紹 1.1 vcpkg安裝GLM 跨平臺C包管理利器vcpkg完全指南 在PowerShell中執行命令&#xff1a; vcpkg install glm# 集成到系…

python文件打包無法導入ultralytics模塊

&#x1f4a5;打包的 .exe 閃退了&#xff1f;別慌&#xff01;教你逐步排查 PyInstaller 打包的所有錯誤&#xff01; &#x1f6e0; 運行 .exe 查看報錯信息? 正確姿勢&#xff1a; ? importlib 動態導入導致打包失敗?什么是動態導入&#xff1f;? 解決方式&#xff1a; …

【React框架】什么是 Vite?如何使用vite自動生成react的目錄?

什么是 Vite&#xff1f; Vite 是一個基于原生 ES Modules 開發的前端構建工具&#xff0c;由 Evan You&#xff08;Vue 的作者&#xff09;開發。它最大的特點包括&#xff1a; 極速冷啟動&#xff1a;因為利用了瀏覽器原生的 ES Modules&#xff0c;所以在開發時無需等待整…

深入解讀 React 純組件(PureComponent)

什么是純組件&#xff1f; React 的純組件(PureComponent)是 React.Component 的一個變體&#xff0c;它通過淺比較(shallow comparison)props 和 state 來自動實現 shouldComponentUpdate() 方法&#xff0c;從而優化性能。 核心特點 1. 自動淺比較&#xff1a; PureCompon…

JavaScript數組方法:`some()`的全面解析與應用

文章目錄 JavaScript數組方法&#xff1a;some()的全面解析與應用一、some()方法的基本概念語法參數說明返回值 二、some()方法的核心特點三、基礎用法示例示例1&#xff1a;檢查數組中是否有大于10的元素示例2&#xff1a;檢查字符串數組中是否包含特定子串 四、實際應用場景1…

判斷兩個 IP 地址是否在同一子網 C

#include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> // 將點分十進制的 IP 地址轉換為 32 位無符號整數 unsigned int ip_to_uint(const char *ip) { struct in_addr addr; if (inet_pton(AF_INET, ip, &am…

React 組件樣式

在這里插入圖片描述 分為行內和css文件控制 行內 通過CSS中類名文件控制

尚硅谷Java第 4、5 章IDEA,數組

第 4 章&#xff1a;IDEA的使用 第 5 章&#xff1a;數組 5.1 數組的概述 數組(Array)&#xff1a;就可以理解為多個數據的組合。 程序中的容器&#xff1a;數組、集合框架&#xff08;List、Set、Map&#xff09;。 數組中的概念&#xff1a; 數組名 下標&#xff08;或索…

SQL注入基本原理靶場實現

? 一、前言 SQL注入漏洞(SQL injection)是WEB層面高危的漏洞之一&#xff0c;也是常見的攻擊方式。 二、本質 1、什么是SQL注入 SQL 注入是一種利用應用程序對用戶輸入數據過濾不嚴格&#xff0c;將惡意 SQL 代碼插入到正常 SQL 語句中&#xff0c;從而操控數據庫查詢邏輯的…

圖像預處理(OpenCV)

1 圖像翻轉(圖像鏡像旋轉) 在OpenCV中&#xff0c;圖片的鏡像旋轉是以圖像的中心為原點進行鏡像翻轉的。 cv2.flip(img,flipcode) 參數 img: 要翻轉的圖像 flipcode: 指定翻轉類型的標志 flipcode0: 垂直翻轉&#xff0c;圖片像素點沿x軸翻轉 flipcode>0: 水平翻轉&…

PCDN收益高低的關鍵因素

PCDN&#xff08;P2P內容分發網絡&#xff09;收益好的三個主要關鍵因素是&#xff1a;硬件配置與性能、網絡環境與質量、業務調度與策略。 1. 硬件配置與性能 設備穩定性與兼容性 PCDN節點需長時間穩定運行&#xff0c;硬件性能直接影響收益。例如&#xff0c;使用高性能CPU、…

『生成內容溯源系統』詳解

生成內容溯源系統詳解 1. 定義與核心目標 生成內容溯源系統&#xff08;Generative Content Provenance System&#xff09;是指能夠追蹤AI生成內容的來源、生成過程、版權歸屬及修改歷史的技術體系。其核心目標是&#xff1a; 驗證真實性&#xff1a;證明內容由特定AI模型生…

conda如何安裝和運行jupyter

在Conda環境中安裝和運行Jupyter Notebook是一項常見且實用的任務&#xff0c;特別是在數據科學和機器學習項目中。以下是使用Conda安裝和運行Jupyter Notebook的步驟&#xff1a; 安裝Jupyter Notebook 首先&#xff0c;確保你的Conda是最新的。打開終端或Anaconda Prompt&a…

QML之Flickable(滾動區域)

Flickable 是 QML 中用于創建可滾動區域的基礎組件&#xff0c;它比 ScrollView 提供更底層的控制&#xff0c;適合需要自定義滾動行為的場景。 基本用法 qml import QtQuick 2.15Flickable {width: 200height: 200contentWidth: 400 // 內容總寬度contentHeight: 800 // 內…

【NumPy科學計算引擎:從基礎操作到高性能實踐】

目錄 前言&#xff1a;技術背景與價值當前技術痛點解決方案概述目標讀者說明 一、技術原理剖析關鍵技術模塊說明技術選型對比 二、實戰演示環境配置核心代碼實現運行結果驗證 三、性能對比測試方法論量化數據對比結果分析 四、最佳實踐推薦方案 ?常見錯誤 ?調試技巧 五、應用…

PandaGPT實戰(1): 環境配置及效果演示

文章目錄 1. 環境安裝2. 數據準備2.1 模型權重獲取2.2 訓練數據準備3. 效果演示3.1 訓練3.2 部署效果PandaGPT是首個無需顯式監督即能跨六種模態執行指令微調任務的基礎模型。它展現出多樣化的多模態能力,包括復雜理解/推理、基于知識的描述以及多輪對話交互。 作為通用型指令…

spring security oauth2.0 使用GitHub

在 Spring Security 中集成 GitHub 的 OAuth 2.0 登錄&#xff0c;可以實現用戶通過 GitHub 賬號快速認證。以下是完整的分步實現指南和代碼示例&#xff1a; 一、前置準備 1. 在 GitHub 注冊 OAuth 應用 訪問 GitHub Settings → Developer settings → OAuth Apps點擊 New …

QT聊天項目DAY01

1.新建初始項目 2.修改UI格式 運行效果 3.創建登錄界面 設計登錄界面UI 設計布局 調整布局間距 往水平布局中拖入標簽和文本輸入框 更換控件名稱并固定高度 添加窗口部件 往現有的資源文件中導入圖片 添加水平布局 4.設置登陸界面為主窗口的核心組件 #pragma once#include &l…

檢測到目標URL存在http host頭攻擊漏洞

漏洞描述 修復措施 方法一&#xff1a; nginx 的 default_server 指令可以定義默認的 server 去處理一些沒有匹配到 server_name 的請求&#xff0c;如果沒有顯式定義&#xff0c;則會選取第一個定義的 server 作為 default_server。 server { …