欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

基于C語言實(shí)現(xiàn)高級(jí)通訊錄的示例代碼

 更新時(shí)間:2023年01月30日 10:31:02   作者:楠舍!  
這篇文章主要為大家詳細(xì)介紹了如何利用C語言實(shí)現(xiàn)一個(gè)高級(jí)通訊錄的功能,文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,需要的小伙伴可以參考一下

前言

前面已經(jīng)寫了一篇簡(jiǎn)易版本通訊錄的實(shí)現(xiàn),下面再來寫一篇功能比較齊全的,可增容,增容空間可自己掌控,也可將數(shù)據(jù)保存起來的,又添加了清空列表等一些功能的高級(jí)通訊錄!

為何要實(shí)現(xiàn)高級(jí)通訊錄

對(duì)于簡(jiǎn)易版本的通訊錄來說,我們是直接指定了通訊錄的大小,通訊錄的空間是直接給死了,那么此時(shí)我們會(huì)發(fā)現(xiàn)兩個(gè)弊端:

第一個(gè)弊端:

假設(shè)我們所添加的聯(lián)系人的個(gè)數(shù),小于,我們給定通訊錄的大小,此時(shí)多余的空間就被浪費(fèi)掉了!又假設(shè)我們添加聯(lián)系人的大小,大于,給定通訊錄的大小,此時(shí)我們發(fā)現(xiàn)通訊錄的空間不夠我們來封裝聯(lián)系人信息了!  此時(shí)我們就得優(yōu)化通信錄給定空間上的問題,不能再給其指定大小的空間,而是讓其空間有靈活性,此時(shí)我們以動(dòng)態(tài)增容的方式來給定通訊錄的空間,就很好的規(guī)避了這一問題!

第二個(gè)弊端:

我們知道程序運(yùn)行起來我們輸入的數(shù)據(jù)都是保存在內(nèi)存上的,在簡(jiǎn)易版本中我們?cè)谶\(yùn)行通訊錄之后添加的數(shù)據(jù),在程序結(jié)束的時(shí)候都會(huì)被清除。當(dāng)?shù)诙芜\(yùn)行起來的時(shí)候,這些數(shù)據(jù)都已經(jīng)不存在了,而我們既然要保存聯(lián)系人的信息,就得做到數(shù)據(jù)持久化的保存,才能真正保存聯(lián)系人信息,要做到持久化我們就得將數(shù)據(jù)保存到硬盤中,也就是文件當(dāng)中,此時(shí)我們可以用文件操作的方式來實(shí)現(xiàn)持久化的保存聯(lián)系人信息,就很好的規(guī)避了這一問題!

高級(jí)通訊錄實(shí)現(xiàn):

為了規(guī)避以上問題,我們?cè)賮韺?shí)現(xiàn)一個(gè)能增容能保存以及再完善一些功能的高級(jí)通訊錄!

創(chuàng)建通訊錄

我們先創(chuàng)建一個(gè)結(jié)構(gòu)體,用來封裝聯(lián)系人的:姓名、性別、年齡...等信息!再創(chuàng)建一個(gè)結(jié)構(gòu)體,用來:操控聯(lián)系人信息、記錄聯(lián)系人個(gè)數(shù)、記錄空間數(shù)....等!

具體實(shí)現(xiàn)看代碼:

#define NAME_SIZE 20
#define EAX_SIZE 6
#define PHONE_SIZE 15
 
//創(chuàng)建封裝通訊錄內(nèi)容的結(jié)構(gòu)體,并給其重命名
typedef struct information
{
    char name[NAME_SIZE];
    int age;
    char eax[EAX_SIZE];
    char phone[PHONE_SIZE];
}information;
 
 
//創(chuàng)建管理通訊錄的結(jié)構(gòu)體,并給其重命名
typedef struct contict
{
    information* data;//結(jié)構(gòu)體指針
    int sz;//聯(lián)系人個(gè)數(shù)
    int count;//增容的數(shù)量
}contict;

打印菜單

我們要?jiǎng)?chuàng)建一個(gè)菜單供用戶選擇,讓用戶選擇操作的功能,此時(shí)我們用do while循環(huán)里面嵌套Switch case語句來實(shí)現(xiàn)用戶對(duì)功能的選擇以及菜單的顯示!,

具體看代碼:

//定義所用到的常量
//因?yàn)槌A刻嘤妹杜e類型一次性定義
//讓這些常量代替我們對(duì)功能的選擇
enum Constant
{
    EXIT,
    ADD,
    DEL,
    SEL,
    MODIFY,
    SHOW,
    SQRT,
    CLEAR
};
 
 
//菜單
void menu(void)
{
    printf("******************************\n");
    printf("***** 1、add   2、del    *****\n");
    printf("***** 3、sel   4、modify *****\n");
    printf("***** 5、show  6、sqrt   *****\n");
    printf("***** 7、clear 0、exit   *****\n");
    printf("******************************\n");
}
 
 
int main()
{
//創(chuàng)建結(jié)構(gòu)體變量
    contict con;
 
    //初始化通訊錄
    init_contict(&con);
 
    int input = 0;
    do
    {
        //菜單
        menu();
        printf("請(qǐng)選擇-> ");
        scanf("%d", &input);
        switch (input)
        {
        case ADD:
            ADDcontict(&con);//添加聯(lián)系人
            break;
        case DEL:
            DELcontict(&con);//刪除指定聯(lián)系人
            break;
        case SEL:
            SELcontict(&con);//查詢指定聯(lián)系人
            break;
        case MODIFY:
            MODIFYcontict(&con);//修改指定聯(lián)系人信息
            break;
        case SHOW:
            SHOWcontict(&con);//顯示所有聯(lián)系人信息
            break;
        case SQRT:
            SQRTcontict(&con);//排序聯(lián)系人
            break;
        case CLEAR:
            CLEARcontict(&con);//清空通訊錄
            break;
        case EXIT:
            SAVEcontictp(&con);//退出的時(shí)候保存通訊錄聯(lián)系人信息
            FREEcontict(&con);//退出的時(shí)候釋放空間
            printf("退出成功\n");
            break;
        default:
            printf("選擇有誤請(qǐng)重新選擇-> \n");
            break;
        }
 
    } while (input);
 
    return 0;
}

先大致了解一下邏輯,而代碼里面的函數(shù)功能,我們下面一一實(shí)現(xiàn)與介紹!

初始化通訊錄

因?yàn)槭莿?dòng)態(tài)增容版本,我們?cè)诔跏蓟臅r(shí)候空間是由我們自行開辟的,而C語言里面給我們提供了動(dòng)態(tài)內(nèi)存開辟的函數(shù),我們按照這樣的思路來開辟空間,先開辟小一點(diǎn)的空間用,如果空間不夠用了我們?cè)僬{(diào)整空間,讓其變大!在初始化開辟空間的時(shí)候,我們使用calloc函數(shù)來申請(qǐng)空間,因?yàn)閏alloc函數(shù)在動(dòng)態(tài)空間申請(qǐng)的時(shí)候會(huì)將空間中的每個(gè)字節(jié)的內(nèi)容都初始化為0,然后我們?cè)賹⒂涗浡?lián)系人的個(gè)數(shù)的變量初始化為0,再將記錄空間數(shù)量的變量初始化為我們所開辟的聯(lián)系人空間的個(gè)數(shù)!

因?yàn)槭悄鼙4媛?lián)系人信息的通訊錄,為了用戶的后續(xù)使用和關(guān)閉,所以在初始化的時(shí)候,還得要調(diào)用一個(gè)功能,就是將保存在文件中的聯(lián)系人的信息讀到我們動(dòng)態(tài)申請(qǐng)的空間中,隨后繼續(xù)進(jìn)行操作,通俗點(diǎn)將就是將已經(jīng)存在的聯(lián)系人的信息拿到通訊錄里面!這個(gè)功能就是加載功能!

具體看代碼實(shí)現(xiàn):

//初始化通訊錄
#define IN 3
void init_contict(contict* pc)
{
    assert(pc);
    //calloc函數(shù)在開辟空間的時(shí)候會(huì)將每個(gè)字節(jié)的內(nèi)容都初始化為0
    information* p = (information*)calloc(IN, sizeof(information));
    //判斷是否開辟成功
    if (p == NULL)
    {
        perror("calloc");
        return;
    }
    pc->data = p;
    pc->sz = 0;
    pc->count = IN;
 
    //加載文件信息到通訊錄中
    read_contict(pc);
    //將原來存在的聯(lián)系人信息拿到通訊錄中
}

實(shí)現(xiàn)加載功能

就是將文件中的聯(lián)系人的信息,加載到通訊錄中,以便后續(xù)操作,完整的實(shí)現(xiàn)了持久化保存功能,比如說:但我們第一次使用通訊錄的時(shí)候會(huì)添加聯(lián)系人的信息,在最后關(guān)閉的時(shí)候,這些信息會(huì)被保存到文件中,當(dāng)我們第二次再進(jìn)行操作的時(shí)候,就將這些保存在文件中的聯(lián)系人信息加載到通訊錄中,以供我們操作,也更完整的實(shí)現(xiàn)了保存功能!具體點(diǎn)說就是對(duì)保存聯(lián)系人信息的文件進(jìn)行讀操作,將文件里的信息讀到通訊錄的空間里!

具體實(shí)現(xiàn)看代碼:

//加載文件信息到通訊錄中
void read_contict(contict* pc)
{
    assert(pc);
    //打開文件
    FILE* pf = fopen("AddressBook.txt", "rb");
    //判斷是否打開成功
    if (pf == NULL)
    {
        perror("fopen");
        return;
    }
    //讀數(shù)據(jù)
    information tmp = { 0 };
    int i = 0;
    while (fread(&tmp, sizeof(information), 1, pf))
    {
        //讀取數(shù)據(jù)要考慮增容問題
        Enhancement(pc);
        pc->data[i] = tmp;
        pc->sz++;
        i++;
    }
    //關(guān)閉文件
    fclose(pf);
    pf = NULL;
}

實(shí)現(xiàn)添加功能

添加聯(lián)系人的方式其實(shí)很簡(jiǎn)單,我們直接在通訊錄里面寫入值就行了,每寫入一個(gè)讓記錄聯(lián)系人個(gè)數(shù)的變量+1,再判斷一下空間的容量夠不夠是否需要增容?。ㄎ覀儗⒃鋈莘庋b成一個(gè)函數(shù),直接調(diào)用一下就行),增容的同時(shí)讓記錄空間的變量同樣變成增容之后空間的個(gè)數(shù)!

具體實(shí)現(xiàn)看代碼:

//添加聯(lián)系人
void ADDcontict(contict* pc)
{
    assert(pc);
    //判斷是否要增容
    Enhancement(pc);//增容功能后續(xù)實(shí)現(xiàn)
 
    printf("請(qǐng)輸入姓名-> ");
    scanf("%s", pc->data[pc->sz].name);
    printf("清輸入年齡-> ");
    scanf("%d", &(pc->data[pc->sz].age));
    printf("請(qǐng)輸入性別-> ");
    scanf("%s", pc->data[pc->sz].eax);
    printf("請(qǐng)輸入電話-> ");
    scanf("%s", pc->data[pc->sz].phone);
    pc->sz++;
    printf("添加成功\n");
}

實(shí)現(xiàn)增容功能

在添加聯(lián)系以及后面我們從文件中讀取聯(lián)系人信息的時(shí)候,我們都可能遇到實(shí)現(xiàn)申請(qǐng)好的空間不夠用的情況,此時(shí)我們就要進(jìn)行調(diào)整空間的大小,讓空間變大也就是增容,我們知道C語言中,realloc函數(shù)(不懂可以看主要?jiǎng)討B(tài)內(nèi)存管理文章),可以調(diào)整申請(qǐng)好的動(dòng)態(tài)空間的大小,所以在實(shí)現(xiàn)增容這個(gè)功能的時(shí)候我們用,realloc函數(shù),來實(shí)現(xiàn)增容空間的功能!增容的同時(shí)我們也讓記錄空間個(gè)數(shù)的變量進(jìn)行增加!

具體實(shí)現(xiàn)看代碼:

//判斷是否要增容
#define IT 2
void Enhancement(contict* pc)
{
    assert(pc);
    if (pc->sz == pc->count)
    {
        //增容
        information* p = (information*)realloc(pc->data, (pc->count + IT) * sizeof(information));
        if (p == NULL)
        {
            perror("realloc");
            return;
        }
        pc->data = p;
        pc->count += IT;
        printf("增容成功\n");
    }
}

實(shí)現(xiàn)刪除功能

實(shí)現(xiàn)刪除指定聯(lián)系人,原理其實(shí)很簡(jiǎn)單,就是將要?jiǎng)h除的聯(lián)系人的信息,被其后面的聯(lián)系人覆蓋掉,以此類推從后往前一直覆蓋直到聯(lián)系人全部遍歷完,通俗點(diǎn)說就是讓其后面的每個(gè)聯(lián)系人都往前走一步!

畫圖簡(jiǎn)單明了:

具體實(shí)現(xiàn)看代碼:

//判斷該聯(lián)系人是否存在
There(char* name, contict* pc)
{
    int i = 0;
    for (i = 0; i < pc->sz; i++)
    {
        if (strcmp(name, pc->data[i].name) == 0)
        {
            return i;
        }
    }
    return -1;
}
 
 
//刪除指定聯(lián)系人
void DELcontict(contict* pc)
{
    assert(pc);
 
    //判斷聯(lián)系人列表是否為空
    if (pc->sz == 0)
    {
        printf("聯(lián)系人列表為空 無法刪除\n");
        return;
    }
 
    char name[NAME_SIZE];
    printf("請(qǐng)輸入要?jiǎng)h除聯(lián)系人的姓名-> ");
    scanf("%s", name);
 
    //判斷該聯(lián)系人是否存在
    int flag = There(name, pc);//因?yàn)楹罄m(xù)功能都要用到這一步,用一個(gè)函數(shù)來封裝!
    if (flag == -1)
    {
        printf("該聯(lián)系人不存在\n");
        return;
    }
 
    //刪除聯(lián)系人
    int i = 0;
    for (i = flag; i < pc->sz - 1; i++)
    {
        pc->data[i] = pc->data[i + 1];
    }
    --pc->sz;
    printf("刪除成功\n");
}

實(shí)現(xiàn)查詢功能

查詢就指定聯(lián)系人就很簡(jiǎn)單了,就只是找到該聯(lián)系人,然后再將該聯(lián)系人的信息打印出來即可!

具體實(shí)現(xiàn)看代碼:

//判斷該聯(lián)系人是否存在
There(char* name, contict* pc)
{
    int i = 0;
    for (i = 0; i < pc->sz; i++)
    {
        if (strcmp(name, pc->data[i].name) == 0)
        {
            return i;
        }
    }
    return -1;
}
 
 
//查找指定聯(lián)系人信息
void SELcontict(contict* pc)
{
    assert(pc);
    if (pc->sz == 0)
    {
        printf("聯(lián)系人列表為空,無法查詢\n");
        return;
    }
 
    char name[NAME_SIZE];
    printf("請(qǐng)輸入要查詢聯(lián)系人的姓名-> ");
    scanf("%s", name);
 
    //判斷該聯(lián)系人是否存在
    int flag = There(name, pc);
    if (flag == -1)
    {
        printf("該聯(lián)系人不存在\n");
        return;
    }
    printf("%-10s  %-5s  %-5s  %-13s\n", "姓名", "年齡", "性別", "電話");
    printf("%-10s  %-5d  %-5s  %-13s\n", pc->data[flag].name,
        pc->data[flag].age,
        pc->data[flag].eax,
        pc->data[flag].phone);
    printf("查詢成功\n");
}

實(shí)現(xiàn)修改功能

修改聯(lián)系人跟查詢聯(lián)系人一個(gè)思路,就是找到該聯(lián)系人的位置,然后將其信息修改掉,也就是用scanf函數(shù)重新給其輸入值即可!

具體實(shí)現(xiàn)看代碼:

//判斷該聯(lián)系人是否存在
There(char* name, contict* pc)
{
    int i = 0;
    for (i = 0; i < pc->sz; i++)
    {
        if (strcmp(name, pc->data[i].name) == 0)
        {
            return i;
        }
    }
    return -1;
}
 
 
//修改指定聯(lián)系人信息
void MODIFYcontict(contict* pc)
{
    assert(pc);
    if (pc->sz == 0)
    {
        printf("聯(lián)系人列表為空,無法修改\n");
        return;
    }
 
    char name[NAME_SIZE];
    printf("請(qǐng)輸入要修改聯(lián)系人的姓名-> ");
    scanf("%s", name);
 
    //判斷該聯(lián)系人是否存在
    int flag = There(name, pc);
    if (flag == -1)
    {
        printf("該聯(lián)系人不存在\n");
        return;
    }
    printf("請(qǐng)輸入姓名-> ");
    scanf("%s", pc->data[flag].name);
    printf("清輸入年齡-> ");
    scanf("%d", &(pc->data[flag].age));
    printf("請(qǐng)輸入性別-> ");
    scanf("%s", pc->data[flag].eax);
    printf("請(qǐng)輸入電話-> ");
    scanf("%s", pc->data[flag].phone);
 
    printf("修改成功\n");
}

實(shí)現(xiàn)查詢所有聯(lián)系人功能

查詢所有聯(lián)系人信息,就是將所有聯(lián)系人信息都打印出來,我們只需要運(yùn)用一個(gè)for遍歷聯(lián)系人列表即可!

具體實(shí)現(xiàn)看代碼:

//顯示所有聯(lián)系人信息
void SHOWcontict(contict* pc)
{
    assert(pc);
    if (pc->sz == 0)
    {
        printf("聯(lián)系人列表為空\(chéng)n");
        return;
    }
    printf("%-10s  %-5s  %-5s  %-13s\n", "姓名", "年齡", "性別", "電話");
    int i = 0;
    for (i = 0; i < pc->sz; i++)
    {
        printf("%-10s  %-5d  %-5s  %-13s\n", pc->data[i].name,
            pc->data[i].age,
            pc->data[i].eax,
            pc->data[i].phone);
    }
}

實(shí)現(xiàn)排序功能

在排序的時(shí)候我們,給定兩種排序方法:按照年齡排序、按照姓名排序 供用戶選擇。用qsort函數(shù)(不了解的可以看主頁(yè)指針進(jìn)階里面有詳細(xì)介紹qsort)來分別實(shí)現(xiàn)兩種排序功能!

具體看代碼:

 
//排序聯(lián)系人信息
 
//按照年齡排序
int con_age(const void* e1, const void* e2)
{
    //升序
    return ((information*)e1)->age - ((information*)e2)->age;
    //降序
    //return ((information*)e2)->age - ((information*)e1)->age;
}
//按照姓名排序
int con_name(const void* e1, const void* e2)
{
    //升序
    return strcmp(((information*)e1)->name, ((information*)e2)->name);
    //降序
    //return strcmp(((information*)e2)->name, ((information*)e1)->name);
}
 
void SQRTcontict(contict* pc)
{
    assert(pc);
    if (pc->sz == 0)
    {
        printf("聯(lián)系人列表為空,無法排序\n");
        return;
    }
    int n = 0;
    printf("*********************\n");
    printf("*** 1、按年齡排序 ***\n");
    printf("*** 2、按姓名排序 ***\n");
    printf("*********************\n");
    printf("請(qǐng)選擇排序方式-> ");
    scanf("%d", &n);
    if (n == 1)
    {
        qsort(pc->data, pc->sz, sizeof(information), con_age);
        printf("按照年齡排序成功\n");
    }
    else if (n == 2)
    {
        qsort(pc->data, pc->sz, sizeof(information), con_name);
        printf("按照姓名排序成功\n");
    }
    else
    {
        printf("選擇排序無效\n");
    }
 
}

實(shí)現(xiàn)清空功能

要清空聯(lián)系人信息,就只需要將我們通訊錄申請(qǐng)的空間釋放掉,隨后再以讀的形式打開一下文件,打開之后什么都不干,讀的形式會(huì)將文件的內(nèi)容都覆蓋掉,會(huì)自動(dòng)清空文件里的內(nèi)容,再關(guān)閉文件,最后調(diào)用一下初始化函數(shù),讓它重新開辟一片空間!就完成清空功能了

具體實(shí)現(xiàn)看代碼:

//清空通訊錄信息
void CLEARcontict(contict* pc)
{
    assert(pc);
    free(pc->data);
    pc->data = NULL;
    //打開文件
    FILE* pf = fopen("AddressBook.txt", "wb");//wb在打開文件的時(shí)候會(huì)覆蓋前面的內(nèi)容!
    if (pf == NULL)
    {
        perror("fopen");
        return;
    }
    //啥都不寫入直接關(guān)閉文件!
    //關(guān)閉文件
    fclose(pf);
    pf = NULL;
    init_contict(pc);
    printf("清空成功\n");
}

實(shí)現(xiàn)保存功能

要讓聯(lián)系人信息持久化的保存,我們將其保存到文件中,進(jìn)行文件操作(不懂看主頁(yè)文件操作文章有詳細(xì)講解),只需要將每個(gè)聯(lián)系人的信息寫入文件中即可!

具體實(shí)現(xiàn)看代碼:

//退出的時(shí)候保存通訊錄聯(lián)系人信息
void SAVEcontictp(contict* pc)
{
    assert(pc);
    //打開文件
    FILE* pf = fopen("AddressBook.txt", "wb");//以二進(jìn)制的寫入形式打開
    //判斷是否打開成功
    if (pf == NULL)
    {
        perror("fopen");
        return;
    }
    //開始寫數(shù)據(jù)
    int i = 0;
    for (i = 0; i < pc->sz; i++)
    {
        //一個(gè)一個(gè)的寫入數(shù)據(jù)
        fwrite(pc->data+i, sizeof(information),1, pf);
    }
    //關(guān)閉文件
    fclose(pf);
    pf = NULL;
    printf("保存成功\n");
}

實(shí)現(xiàn)退出功能

在退出的時(shí)候,先將通訊錄里面聯(lián)系人的信息,保存到文件中,隨后再將動(dòng)態(tài)開辟的通訊錄的空間釋放就行,隨后將指針置為NULL,避免野指針。注意:先保存再釋放二者順序不可亂,不然會(huì)出錯(cuò)!

具體實(shí)現(xiàn)看代碼:

//退出的時(shí)候釋放空間
void FREEcontict(contict* pc)
{
    assert(pc);
    free(pc->data);
    pc->data = NULL;
    pc->sz = 0;
    pc->count = 0;
}

通訊錄總代碼

//動(dòng)態(tài)+可保存數(shù)據(jù)版本的通訊錄
 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
 
//創(chuàng)建封裝通訊錄內(nèi)容的結(jié)構(gòu)體
#define NAME_SIZE 20
#define EAX_SIZE 6
#define PHONE_SIZE 15
typedef struct information
{
	char name[NAME_SIZE];
	int age;
	char eax[EAX_SIZE];
	char phone[PHONE_SIZE];
}information;
 
//創(chuàng)建管理通訊錄的結(jié)構(gòu)體
typedef struct contict
{
	information* data;//結(jié)構(gòu)體指針
	int sz;//聯(lián)系人個(gè)數(shù)
	int count;//增容的數(shù)量
}contict;
 
//定義所用到的常量
//因?yàn)槌A刻嘤妹杜e類型一次性定義
//讓這些常量代替我們對(duì)功能的選擇
enum Constant
{
	EXIT,
	ADD,
	DEL,
	SEL,
	MODIFY,
	SHOW,
	SQRT,
	CLEAR
};
 
 
//菜單
void menu(void)
{
	printf("******************************\n");
	printf("***** 1、add   2、del    *****\n");
	printf("***** 3、sel   4、modify *****\n");
	printf("***** 5、show  6、sqrt   *****\n");
	printf("***** 7、clear 0、exit   *****\n");
	printf("******************************\n");
}
 
//判斷是否要增容
#define IT 2
void Enhancement(contict* pc)
{
	assert(pc);
	if (pc->sz == pc->count)
	{
		//增容
		information* p = (information*)realloc(pc->data, (pc->count + IT) * sizeof(information));
		if (p == NULL)
		{
			perror("realloc");
			return;
		}
		pc->data = p;
		pc->count += IT;
		printf("增容成功\n");
	}
}
 
 
//加載文件信息到通訊錄中
void read_contict(contict* pc)
{
	assert(pc);
	//打開文件
	FILE* pf = fopen("AddressBook.txt", "rb");
	//判斷是否打開成功
	if (pf == NULL)
	{
		perror("fopen");
		return;
	}
	//讀數(shù)據(jù)
	information tmp = { 0 };
	int i = 0;
	while (fread(&tmp, sizeof(information), 1, pf))
	{
		//讀取數(shù)據(jù)要考慮增容問題
		Enhancement(pc);
		pc->data[i] = tmp;
		pc->sz++;
		i++;
	}
	//關(guān)閉文件
	fclose(pf);
	pf = NULL;
}
 
 
 
//初始化通訊錄
#define IN 3
void init_contict(contict* pc)
{
	assert(pc);
	//calloc函數(shù)在開辟空間的時(shí)候會(huì)將每個(gè)字節(jié)的內(nèi)容都初始化為0
	information* p = (information*)calloc(IN, sizeof(information));
	//判斷是否開辟成功
	if (p == NULL)
	{
		perror("calloc");
		return;
	}
	pc->data = p;
	pc->sz = 0;
	pc->count = IN;
 
	//加載文件信息到通訊錄中
	read_contict(pc);
	//先不用管這個(gè)功能后續(xù)會(huì)慢慢了解
	//主要了解上面初始化的代碼!
}
 
 
 
 
//添加聯(lián)系人
void ADDcontict(contict* pc)
{
	assert(pc);
	//判斷是否要增容
	Enhancement(pc);
 
	printf("請(qǐng)輸入姓名-> ");
	scanf("%s", pc->data[pc->sz].name);
	printf("清輸入年齡-> ");
	scanf("%d", &(pc->data[pc->sz].age));
	printf("請(qǐng)輸入性別-> ");
	scanf("%s", pc->data[pc->sz].eax);
	printf("請(qǐng)輸入電話-> ");
	scanf("%s", pc->data[pc->sz].phone);
	pc->sz++;
	printf("添加成功\n");
}
 
//判斷該聯(lián)系人是否存在
There(char* name, contict* pc)
{
	int i = 0;
	for (i = 0; i < pc->sz; i++)
	{
		if (strcmp(name, pc->data[i].name) == 0)
		{
			return i;
		}
	}
	return -1;
}
 
//刪除指定聯(lián)系人
void DELcontict(contict* pc)
{
	assert(pc);
 
	//判斷聯(lián)系人列表是否為空
	if (pc->sz == 0)
	{
		printf("聯(lián)系人列表為空 無法刪除\n");
		return;
	}
 
	char name[NAME_SIZE];
	printf("請(qǐng)輸入要?jiǎng)h除聯(lián)系人的姓名-> ");
	scanf("%s", name);
 
	//判斷該聯(lián)系人是否存在
	int flag = There(name, pc);
	if (flag == -1)
	{
		printf("該聯(lián)系人不存在\n");
		return;
	}
 
	//刪除聯(lián)系人
	int i = 0;
	for (i = flag; i < pc->sz - 1; i++)
	{
		pc->data[i] = pc->data[i + 1];
	}
	--pc->sz;
	printf("刪除成功\n");
}
 
 
//查找指定聯(lián)系人信息
void SELcontict(contict* pc)
{
	assert(pc);
	if (pc->sz == 0)
	{
		printf("聯(lián)系人列表為空,無法查詢\n");
		return;
	}
 
	char name[NAME_SIZE];
	printf("請(qǐng)輸入要查詢聯(lián)系人的姓名-> ");
	scanf("%s", name);
 
	//判斷該聯(lián)系人是否存在
	int flag = There(name, pc);
	if (flag == -1)
	{
		printf("該聯(lián)系人不存在\n");
		return;
	}
	printf("%-10s  %-5s  %-5s  %-13s\n", "姓名", "年齡", "性別", "電話");
	printf("%-10s  %-5d  %-5s  %-13s\n", pc->data[flag].name,
		pc->data[flag].age,
		pc->data[flag].eax,
		pc->data[flag].phone);
	printf("查詢成功\n");
}
 
 
//修改指定聯(lián)系人信息
void MODIFYcontict(contict* pc)
{
	assert(pc);
	if (pc->sz == 0)
	{
		printf("聯(lián)系人列表為空,無法修改\n");
		return;
	}
 
	char name[NAME_SIZE];
	printf("請(qǐng)輸入要修改聯(lián)系人的姓名-> ");
	scanf("%s", name);
 
	//判斷該聯(lián)系人是否存在
	int flag = There(name, pc);
	if (flag == -1)
	{
		printf("該聯(lián)系人不存在\n");
		return;
	}
	printf("請(qǐng)輸入姓名-> ");
	scanf("%s", pc->data[flag].name);
	printf("清輸入年齡-> ");
	scanf("%d", &(pc->data[flag].age));
	printf("請(qǐng)輸入性別-> ");
	scanf("%s", pc->data[flag].eax);
	printf("請(qǐng)輸入電話-> ");
	scanf("%s", pc->data[flag].phone);
 
	printf("修改成功\n");
}
 
 
//顯示所有聯(lián)系人信息
void SHOWcontict(contict* pc)
{
	assert(pc);
	if (pc->sz == 0)
	{
		printf("聯(lián)系人列表為空\(chéng)n");
		return;
	}
	printf("%-10s  %-5s  %-5s  %-13s\n", "姓名", "年齡", "性別", "電話");
	int i = 0;
	for (i = 0; i < pc->sz; i++)
	{
		printf("%-10s  %-5d  %-5s  %-13s\n", pc->data[i].name,
			pc->data[i].age,
			pc->data[i].eax,
			pc->data[i].phone);
	}
}
 
 
//排序聯(lián)系人信息
 
//按照年齡排序
int con_age(const void* e1, const void* e2)
{
	//升序
	return ((information*)e1)->age - ((information*)e2)->age;
	//降序
	//return ((information*)e2)->age - ((information*)e1)->age;
}
//按照姓名排序
int con_name(const void* e1, const void* e2)
{
	//升序
	return strcmp(((information*)e1)->name, ((information*)e2)->name);
	//降序
	//return strcmp(((information*)e2)->name, ((information*)e1)->name);
}
 
void SQRTcontict(contict* pc)
{
	assert(pc);
	if (pc->sz == 0)
	{
		printf("聯(lián)系人列表為空,無法排序\n");
		return;
	}
	int n = 0;
	printf("*********************\n");
	printf("*** 1、按年齡排序 ***\n");
	printf("*** 2、按姓名排序 ***\n");
	printf("*********************\n");
	printf("請(qǐng)選擇排序方式-> ");
	scanf("%d", &n);
	if (n == 1)
	{
		qsort(pc->data, pc->sz, sizeof(information), con_age);
		printf("按照年齡排序成功\n");
	}
	else if (n == 2)
	{
		qsort(pc->data, pc->sz, sizeof(information), con_name);
		printf("按照姓名排序成功\n");
	}
	else
	{
		printf("選擇排序無效\n");
	}
 
}
 
 
//清空通訊錄信息
void CLEARcontict(contict* pc)
{
	assert(pc);
	free(pc->data);
	pc->data = NULL;
	//打開文件
	FILE* pf = fopen("AddressBook.txt", "wb");//wb在打開文件的時(shí)候會(huì)覆蓋前面的內(nèi)容!
	if (pf == NULL)
	{
		perror("fopen");
		return;
	}
	//啥都不寫入直接關(guān)閉文件!
	//關(guān)閉文件
	fclose(pf);
	pf = NULL;
	init_contict(pc);
	printf("清空成功\n");
}
 
 
//退出的時(shí)候釋放空間
void FREEcontict(contict* pc)
{
	assert(pc);
	free(pc->data);
	pc->data = NULL;
	pc->sz = 0;
	pc->count = 0;
}
 
 
//退出的時(shí)候保存通訊錄聯(lián)系人信息
void SAVEcontictp(contict* pc)
{
	assert(pc);
	//打開文件
	FILE* pf = fopen("AddressBook.txt", "wb");//以二進(jìn)制的寫入形式打開
	//判斷是否打開成功
	if (pf == NULL)
	{
		perror("fopen");
		return;
	}
	//開始寫數(shù)據(jù)
	int i = 0;
	for (i = 0; i < pc->sz; i++)
	{
		//一個(gè)一個(gè)的寫入數(shù)據(jù)
		fwrite(pc->data+i, sizeof(information),1, pf);
	}
	//關(guān)閉文件
	fclose(pf);
	pf = NULL;
	printf("保存成功\n");
}
 
 
 
 
//通訊錄
void Test(void)
{
	//創(chuàng)建結(jié)構(gòu)體變量
	contict con;
 
	//初始化通訊錄
	init_contict(&con);
 
	int input = 0;
	do
	{
		//菜單
		menu();
		printf("請(qǐng)選擇-> ");
		scanf("%d", &input);
		switch (input)
		{
		case ADD:
			ADDcontict(&con);//添加聯(lián)系人
			break;
		case DEL:
			DELcontict(&con);//刪除指定聯(lián)系人
			break;
		case SEL:
			SELcontict(&con);//查詢指定聯(lián)系人
			break;
		case MODIFY:
			MODIFYcontict(&con);//修改指定聯(lián)系人信息
			break;
		case SHOW:
			SHOWcontict(&con);//顯示所有聯(lián)系人信息
			break;
		case SQRT:
			SQRTcontict(&con);//排序聯(lián)系人
			break;
		case CLEAR:
			CLEARcontict(&con);//清空通訊錄
			break;
		case EXIT:
			SAVEcontictp(&con);//退出的時(shí)候保存通訊錄聯(lián)系人信息
			FREEcontict(&con);//退出的時(shí)候釋放空間
			printf("退出成功\n");
			break;
		default:
			printf("選擇有誤請(qǐng)重新選擇-> \n");
			break;
		}
 
 
	} while (input);
}
 
int main()
{
 
	//測(cè)試通訊錄
	Test();
 
	return 0;
}

以上就是基于C語言實(shí)現(xiàn)高級(jí)通訊錄的示例代碼的詳細(xì)內(nèi)容,更多關(guān)于C語言高級(jí)通訊錄的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評(píng)論