柚子快報(bào)邀請碼778899分享:數(shù)據(jù)結(jié)構(gòu)之實(shí)現(xiàn)“通訊錄”
柚子快報(bào)邀請碼778899分享:數(shù)據(jù)結(jié)構(gòu)之實(shí)現(xiàn)“通訊錄”
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?大家先贊后看,養(yǎng)成好習(xí)慣
你們的點(diǎn)贊和關(guān)注還有收藏就是我的動(dòng)力!?。?/p>
目錄
前言
一、通訊錄文件的創(chuàng)建和聯(lián)系人結(jié)構(gòu)體定義
1.1 文件創(chuàng)建
1.2 聯(lián)系人結(jié)構(gòu)體定義
二、通訊錄的功能實(shí)現(xiàn)
2.1通訊錄初始化
2.2通訊錄銷毀
2.3添加聯(lián)系人
2.4刪除聯(lián)系人
2.5查找聯(lián)系人(包含顯現(xiàn)聯(lián)系人)
2.6修改通訊錄
2.7展示通訊錄
2.8菜單的創(chuàng)建 (與掃雷、猜數(shù)字相似)
三、使用通訊錄儲存聯(lián)系人
四、結(jié)合文件操作來儲存信息
五、代碼展示
5.1通訊錄頭文件
5.2通訊錄源文件?
總結(jié)
前言
“通訊錄”是基于順序表的基礎(chǔ)上實(shí)現(xiàn)的項(xiàng)目,要熟悉順序表才比較容易看懂和完成通訊錄項(xiàng)目。在這個(gè)博客里面不會來介紹之前的東西,之前沒看懂的可以到這【數(shù)據(jù)結(jié)構(gòu)之“順序表”】-CSDN博客
一、通訊錄文件的創(chuàng)建和聯(lián)系人結(jié)構(gòu)體定義
1.1 文件創(chuàng)建
加上之前順序表的兩個(gè)文件一共是五個(gè)文件。
test.c是實(shí)現(xiàn)聯(lián)系人儲存的文件,contact.c是通訊錄的源文件,contact.h是通訊錄的頭文件,seqlist.c和seqlist.h是之前的順序表的源文件和頭文件。(源文件是功能實(shí)現(xiàn)的代碼,頭文件是用來包含一些頭文件和定義一些東西)
1.2 聯(lián)系人結(jié)構(gòu)體定義
我們這里的聯(lián)系人信息包含:姓名、性別、年齡 、電話、地址
typedef struct PersonInfo//通訊錄
{
char name[Max_name];//姓名
char gender[Max_gender];//性別
int age;//年齡
char tel[Max_tel];//電話
char addr[Max_addr];//地址
}PeoInfo;//命名為PeoInfo
二、通訊錄的功能實(shí)現(xiàn)
2.1通訊錄初始化
我們就調(diào)用一下順序表的初始化就可以了,因?yàn)樵陧樞虮淼腶rr中存放每一個(gè)結(jié)構(gòu)體(也就是聯(lián)系人的信息)就是PersonInfo。
//通訊錄初始化
void contactInit(contact * con)
{
//這里的con就是sl也就是一個(gè)結(jié)構(gòu)體指針初始化為NULL
//我們直接調(diào)用順序表的初始化
SLInit(con);//初始化
}
2.2通訊錄銷毀
銷毀也同初始化,直接調(diào)用順序表的銷毀。
//通訊錄銷毀
void contactDestroy(contact* con)
{
SLDestroy(con);//銷毀
}
2.3添加聯(lián)系人
也就是給結(jié)構(gòu)體里面的人賦初值,然后調(diào)用一下順序表的插入函數(shù)(頭插、尾插都行)。
//添加通訊錄聯(lián)系人
void contactAdd(contact* con)
{
PeoInfo info;//同SL sl;定義一個(gè)結(jié)構(gòu)體,方便使用
printf("請輸入聯(lián)系人姓名:\n");
scanf("%s", info.name);
printf("請輸入聯(lián)系人性別:\n");
scanf("%s", info.gender);
printf("請輸入聯(lián)系人年齡:\n");
scanf("%d", &info.age);
printf("請輸入聯(lián)系人電話:\n");
scanf("%s", info.tel);
printf("請輸入聯(lián)系人地址:\n");
scanf("%s", info.addr);
SLPushFront(con,info);//頭插聯(lián)系人
printf("添加聯(lián)系人成功!\n");
}
2.4刪除聯(lián)系人
刪除聯(lián)系人有很多方法,可以通過姓名、性別、年齡 、電話、地址 五種方法隨便選擇一種。
我這里演示的是通過姓名來刪除聯(lián)系人,剩下的幾種大家可以自行嘗試!!。
想法我們要遍歷每一個(gè)結(jié)構(gòu)體里面的info.name然后判斷與要被刪除的聯(lián)系人姓名,然后返回下標(biāo)進(jìn)行了(順序表本質(zhì)就是一個(gè)數(shù)組,可以通過下標(biāo)來找到),調(diào)用查找聯(lián)系人返回下標(biāo)函數(shù),我們比較的是字符使用要用strcmp函數(shù),然后調(diào)用一下順序表指定位置的刪除就可以了。
//查找聯(lián)系人,并返回下標(biāo)
int contactFindName(contact* con,char name[Max_name])
{
//還可以通過其他來返回下標(biāo),地址,電話都行,要看傳來的參數(shù)是什么。
for (int i = 0;i < con->size;i++)
{
if (0 == strcmp(con->arr[i].name, name))//strcmp字符串比較函數(shù)
{
//找到了
return i;
}
}
//沒找到
return -1;
}
//刪除聯(lián)系人
void contactDel(contact* con)
{
//刪除前要檢查刪除的數(shù)據(jù)是否存在
//就要先查找數(shù)據(jù)
char name[Max_name];
printf("請輸入你要?jiǎng)h除的聯(lián)系人姓名:\n");
scanf("%s", name);
int pos = contactFindName(con, name);
if (pos < 0)
{
printf("刪除的聯(lián)系人不存在!\n");
return;
}
SLErase(con,pos);//pos是刪除元素的下標(biāo)
printf("刪除成功!\n");
}
2.5查找聯(lián)系人(包含顯現(xiàn)聯(lián)系人)
查找聯(lián)系人和刪除聯(lián)系人很像,只比刪除聯(lián)系人少了刪除數(shù)據(jù)。
//查找通訊錄聯(lián)系人
void contactFind(contact* con)
{
char name[Max_name];
printf("請輸入查找的聯(lián)系人姓名:\n");
scanf("%s", name);
int pos = contactFindName(con, name);
if (pos < 0)
{
printf("查找的聯(lián)系人不存在,查找失?。n");
return;
}
printf("查找成功\n");
printf("姓名 性別 年齡 電話 地址\n");
printf("%-5s %2s %3d %5s %5s\n", con->arr[pos].name,
con->arr[pos].gender,
con->arr[pos].age,
con->arr[pos].tel,
con->arr[pos].addr);
}
2.6修改通訊錄
本質(zhì)上和刪除差不多,還是通過返回下標(biāo)來重新修改聯(lián)系人
//修改通訊錄聯(lián)系人
void contactModify(contact* con)
{
char name[Max_name];
printf("請輸入要修改的聯(lián)系人名字:\n");
scanf("%s", name);
int pos = contactFindName(con,name);
if (pos < 0)
{
printf("修改的聯(lián)系人不存在,修改失?。n");
return;
}
PeoInfo info;
printf("請輸入修改后聯(lián)系人姓名:\n");
scanf("%s", con->arr[pos].name);
printf("請輸入修改后聯(lián)系人性別:\n");
scanf("%s", con->arr[pos].gender);
printf("請輸入修改后聯(lián)系人年齡:\n");
scanf("%d", &con->arr[pos].age);
printf("請輸入修改后聯(lián)系人電話:\n");
scanf("%s", con->arr[pos].tel);
printf("請輸入修改后聯(lián)系人地址:\n");
scanf("%s", con->arr[pos].addr);
printf("修改成功!\n");
}
2.7展示通訊錄
通過循環(huán)來打印聯(lián)系人信息,這時(shí)就要用到順序表里面的有效個(gè)數(shù)(size)來作為循環(huán)的判斷條件。
//展示通訊錄聯(lián)系人
void contactShow(contact* con)
{
for (int i = 0;i < con->size;i++)//呈現(xiàn)所有的信息
{
printf("姓名 性別 年齡 電話 地址\n");
printf("%-5s %2s %3d %5s %5s\n", con->arr[i].name,
con->arr[i].gender,
con->arr[i].age,
con->arr[i].tel,
con->arr[i].addr);
}
printf("呈現(xiàn)完畢!\n");
}
2.8菜單的創(chuàng)建 (與掃雷、猜數(shù)字相似)
void menu()//菜單 目錄
{
printf("***********通訊錄**********\n");
printf("**1.添加用戶***2.刪除用戶**\n");
printf("**3.查找用戶***4.修改用戶**\n");
printf("**5.顯示用戶***0.退出程序**\n");
}
三、使用通訊錄儲存聯(lián)系人
#define _CRT_SECURE_NO_WARNINGS
//用來測試代碼
#include"Seqlist.h"
int main()
{
contact con;
contactInit(&con);//初始化
int input = -1;
do
{
menu();
printf("請你選擇操作:\n");
scanf("%d", &input);
switch (input)
{
case 1:
contactAdd(&con);
break;
case 2:
contactDel(&con);
break;
case 3:
contactFind(&con);
break;
case 4:
contactModify(&con);
break;
case 5:
contactShow(&con);
break;
default:
printf("輸入操作錯(cuò)誤,重新輸入!\n");
break;//default 后面break 可寫可不寫
}
}
while (input);//input 等價(jià)于 input!=0
contactDestroy(&con);//銷毀
return 0;
}
這是主函數(shù)(切忌倆個(gè)頭文件互相包含)
我來演示一下
聯(lián)系人 姓名:恐龍、性別:男、年齡:18、電話:666666、地址:侏羅紀(jì)公園。
拼音不好見諒!?。。?/p>
四、結(jié)合文件操作來儲存信息
這里就不細(xì)講了文件操作,可以看之前的??????喉嚨疼的恐龍又來給大家介紹”芝士了“ 那就是文件操作-CSDN博客
//讀取數(shù)據(jù)到contact.txt文件中
void contactLoad(contact* con)
{
FILE* pf = fopen("contact.txt","rb");//二進(jìn)制讀
if (pf = NULL)
{
perror("fopen error:");
return;
}
PeoInfo info;
while (fread(&info, sizeof(info), 1, pf))
{
SLPushFront(con, info);
}
fclose(pf);//關(guān)閉
pf = NULL;//防止出現(xiàn)空指針
printf("歷史數(shù)據(jù)讀取成功!\n");
}
//寫數(shù)據(jù)到contact.txt文件中
void contactSave(contact* con)
{
FILE* pf = fopen("contact.txt","wb");
if (pf == NULL)
{
perror("fopen error!");
return;
}
for (int sz = 0;sz < con->size;sz++)
{
fwrite(con->arr+sz, sizeof(PeoInfo), 1, pf);//con->arr[sz]不行,這里要地址,&con->arr[sz].
}
fclose(pf);//關(guān)閉
pf = NULL;//防止出現(xiàn)空指針
printf("通訊錄數(shù)據(jù)保存成功!\n");
}
五、代碼展示
5.1通訊錄頭文件
contact.h
#pragma once
#define Max_name 20
#define Max_gender 10
#define Max_tel 15
#define Max_addr 20
typedef struct Seqlist contact;//前置聲明,因?yàn)椴豢梢韵嗷グ^文件,會報(bào)錯(cuò)。
//總結(jié)通訊錄項(xiàng)目的原理:基于順序表,在順序表的數(shù)組中存放每一個(gè)結(jié)構(gòu)體(也就是聯(lián)系人的信息)
typedef struct PersonInfo//通訊錄
{
char name[Max_name];//姓名
char gender[Max_gender];//性別
int age;//年齡
char tel[Max_tel];//電話
char addr[Max_addr];//地址
}PeoInfo;
//通訊錄初始化
void contactInit(contact* con);
//通訊錄的銷毀
void contactDestroy(contact* con);
//添加通訊錄聯(lián)系人
void contactAdd(contact* con);
//刪除通訊錄聯(lián)系人
void contactDel(contact* con);
//查找通訊錄聯(lián)系人
void contactFind(contact* con);
//修改通訊錄聯(lián)系人
void contactModify(contact* con);
//展示通訊錄聯(lián)系人
void contactShow(contact* con);
5.2通訊錄源文件?
contact.c
#define _CRT_SECURE_NO_WARNINGS
#include"Contact.h"
#include"Seqlist.h"
//讀取數(shù)據(jù)到contact.txt文件中
void contactLoad(contact* con)
{
FILE* pf = fopen("contact.txt","rb");//二進(jìn)制讀
if (pf = NULL)
{
perror("fopen error:");
return;
}
PeoInfo info;
while (fread(&info, sizeof(info), 1, pf))
{
SLPushFront(con, info);
}
fclose(pf);//關(guān)閉
pf = NULL;//防止出現(xiàn)空指針
printf("歷史數(shù)據(jù)讀取成功!\n");
}
//寫數(shù)據(jù)到contact.txt文件中
void contactSave(contact* con)
{
FILE* pf = fopen("contact.txt","wb");
if (pf == NULL)
{
perror("fopen error!");
return;
}
for (int sz = 0;sz < con->size;sz++)
{
fwrite(con->arr+sz, sizeof(PeoInfo), 1, pf);//con->arr[sz]不行,這里要地址,&con->arr[sz].
}
fclose(pf);//關(guān)閉
pf = NULL;//防止出現(xiàn)空指針
printf("通訊錄數(shù)據(jù)保存成功!\n");
}
//通訊錄初始化
void contactInit(contact * con)
{
//這里的con就是sl也就是一個(gè)結(jié)構(gòu)體指針初始化為NULL
//我們直接調(diào)用順序表的初始化
SLInit(con);//初始化
}
//通訊錄銷毀
void contactDestroy(contact* con)
{
SLDestroy(con);//銷毀
}
//添加通訊錄聯(lián)系人
void contactAdd(contact* con)
{
PeoInfo info;//同SL sl;定義一個(gè)結(jié)構(gòu)體,方便使用
printf("請輸入聯(lián)系人姓名:\n");
scanf("%s", info.name);
printf("請輸入聯(lián)系人性別:\n");
scanf("%s", info.gender);
printf("請輸入聯(lián)系人年齡:\n");
scanf("%d", &info.age);
printf("請輸入聯(lián)系人電話:\n");
scanf("%s", info.tel);
printf("請輸入聯(lián)系人地址:\n");
scanf("%s", info.addr);
SLPushFront(con,info);//頭插聯(lián)系人
printf("添加聯(lián)系人成功!\n");
}
//查找聯(lián)系人,并返回下標(biāo)
int contactFindName(contact* con,char name[Max_name])
{
//還可以通過其他來返回下標(biāo),地址,電話都行,要看傳來的參數(shù)是什么。
for (int i = 0;i < con->size;i++)
{
if (0 == strcmp(con->arr[i].name, name))//strcmp字符串比較函數(shù)
{
//找到了
return i;
}
}
//沒找到
return -1;
}
//刪除聯(lián)系人
void contactDel(contact* con)
{
//刪除前要檢查刪除的數(shù)據(jù)是否存在
//就要先查找數(shù)據(jù)
char name[Max_name];
printf("請輸入你要?jiǎng)h除的聯(lián)系人姓名:\n");
scanf("%s", name);
int pos = contactFindName(con, name);
if (pos < 0)
{
printf("刪除的聯(lián)系人不存在!\n");
return;
}
SLErase(con,pos);//pos是刪除元素的下標(biāo)
printf("刪除成功!\n");
}
//查找通訊錄聯(lián)系人
void contactFind(contact* con)//err
{
char name[Max_name];
printf("請輸入查找的聯(lián)系人姓名:\n");
scanf("%s", name);
int pos = contactFindName(con, name);
if (pos < 0)
{
printf("查找的聯(lián)系人不存在,查找失??!\n");
return;
}
printf("查找成功\n");
printf("姓名 性別 年齡 電話 地址\n");
printf("%-5s %2s %3d %5s %5s\n", con->arr[pos].name,
con->arr[pos].gender,
con->arr[pos].age,
con->arr[pos].tel,
con->arr[pos].addr);
}
//修改通訊錄聯(lián)系人
void contactModify(contact* con)
{
char name[Max_name];
printf("請輸入要修改的聯(lián)系人名字:\n");
scanf("%s", name);
int pos = contactFindName(con,name);
if (pos < 0)
{
printf("修改的聯(lián)系人不存在,修改失??!\n");
return;
}
PeoInfo info;
printf("請輸入修改后聯(lián)系人姓名:\n");
scanf("%s", con->arr[pos].name);
printf("請輸入修改后聯(lián)系人性別:\n");
scanf("%s", con->arr[pos].gender);
printf("請輸入修改后聯(lián)系人年齡:\n");
scanf("%d", &con->arr[pos].age);
printf("請輸入修改后聯(lián)系人電話:\n");
scanf("%s", con->arr[pos].tel);
printf("請輸入修改后聯(lián)系人地址:\n");
scanf("%s", con->arr[pos].addr);
printf("修改成功!\n");
}
//展示通訊錄聯(lián)系人
void contactShow(contact* con)
{
for (int i = 0;i < con->size;i++)//呈現(xiàn)所有的信息
{
printf("姓名 性別 年齡 電話 地址\n");
printf("%-5s %2s %3d %5s %5s\n", con->arr[i].name,
con->arr[i].gender,
con->arr[i].age,
con->arr[i].tel,
con->arr[i].addr);
}
printf("呈現(xiàn)完畢!\n");
}
總結(jié)
通訊錄這個(gè)項(xiàng)目你只要完全了解了順序表解決不困難,要理解通訊錄結(jié)構(gòu)體每一個(gè)聯(lián)系人就是順序表中的arr動(dòng)態(tài)數(shù)組里面的一個(gè)成員。我們還可以把這些聯(lián)系人的信息以文件的形式儲存起來,這就要運(yùn)用到我們之前學(xué)習(xí)過的文件操作。本人感覺順序表和通訊錄會比鏈表復(fù)雜,后面還會為大家介紹單鏈表和雙鏈表,大家敬請期待吧!!
柚子快報(bào)邀請碼778899分享:數(shù)據(jù)結(jié)構(gòu)之實(shí)現(xiàn)“通訊錄”
文章來源
本文內(nèi)容根據(jù)網(wǎng)絡(luò)資料整理,出于傳遞更多信息之目的,不代表金鑰匙跨境贊同其觀點(diǎn)和立場。
轉(zhuǎn)載請注明,如有侵權(quán),聯(lián)系刪除。