1.功能實現
功能要求
1)至少能夠存儲100個人的通訊信息
2)能夠保存用戶信息:名字、性別、年齡、電話、地址等
3)增加聯系人信息
4)刪除指定聯系人
5)查找制定聯系人
6)修改指定聯系人
7)顯聯系人信息
2.與順序表的關系
3.代碼實現
1.通訊錄基本結構Contact.h
Contact.h
文件代碼如下
#define _CRT_SECURE_NO_WARNINGS 1
#define NAME_MAX 100
#define SEX_MAX 10
#define TEL_MAX 15
#define ADDR_MAX 100//創建通訊錄的結構
typedef struct ContactInfo
{char name[NAME_MAX];char sex[SEX_MAX];int age;char tel[TEL_MAX];char addr[ADDR_MAX];
}CInfo;typedef struct SeqList contact;//此處相當于把順序表的名字改為通訊錄,也可以理解為我把順序表的SL改為了contact,不容易搞混
//因為并沒有調用"SeqList.h"里面的數據或者函數,所以這里不需要調用void ContactInit(contact* pcon); //通訊錄的創建
void ContactDestroy(contact* pcon); //通訊錄的銷毀void ContactAdd(contact* *pcon); //添加聯系人
void ContactDel(contact* pcon); //刪除聯系人void ContactModify(contact* pcon); //修改聯系人
void Contactshow(contact* pcon); //打印聯系人void ContactFind(contact* pcon); //查找聯系人
2.基于通訊錄SqList.h
文件的改進
需要把順序表的數據類型改為通訊錄的結構體,這里就體現了之前在順序表把
int
類型通過typedef
聲明為SLDataType
的好處,可以很方便的更換順序表的類型,不用一個個改。
SqList.h
文件代碼如下
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include"Contact.h"typedef CInfo SLDataType;
//typedef int SLDataType;
//把順序表的數據結構改為通訊錄的結構體類型typedef struct SeqList
{SLDataType* a;int size; // 有效數據int capacity; // 空間容量
}SL;void SLInit(SL* ps); // 數據表初始化
void SLDestroy(SL* ps); // 數據表銷毀void SLPushFront(SL* ps, SLDataType x); // 頭插
void SLPushBack(SL* ps, SLDataType x); // 尾插void SLPopFront(SL* ps); // 頭刪
void SLPopBack(SL* ps); // 尾刪void SLCheckCapacity(SL* ps); // 檢查內存是否足夠,不夠就擴容。
void SLprintf(SL* ps); // 數據表打印void SLInsert(SL* ps, int pos, SLDataType x); //任意下標位置的插入
void SLErase(SL* ps, int pos); //任意下標位置的刪除
3通訊錄運行文件Contact.c
1. 通訊錄的創建ContactInit
只需要調用順序表的初始化就可以啦
void ContactInit(contact* pcon)
{SLInit(pcon);
}
2.通訊錄的銷毀ContactDestroy
一樣的道理,順序表都銷毀了,基于它的通訊錄還好存在嗎?所以自己調用順序表的銷毀就OK啦
void ContactDestroy(contact* pcon)
{SLDestroy(pcon);
}
3.添加聯系人
到這里就需要創建個通訊錄結構體(info
),然后輸入值到通訊錄的結構體中,隨便打印個提示界面,然后記得調用順序表的尾插操作,通過info
把數據插入到順序表中,因為順序表的數據類型是CInfo
也就是struct ContactInfo
,所以并不沖突。
void ContactAdd(contact** pcon)
{CInfo info;printf("請輸入聯系人的姓名:\n");scanf("%s", info.name);printf("請輸入聯系人的性別:\n");scanf("%s", info.sex);printf("請輸入聯系人的年齡:\n");scanf("%d", &info.age);printf("請輸入聯系人的電話:\n");scanf("%s", info.tel);printf("請輸入聯系人的住址:\n");scanf("%s", info.addr);SLPushBack(pcon, info);
}
4.刪除聯系人
有了創建自然就有刪除,但是刪除刪除哪里了,所以還要個查找操作
int FindByName(contact* pcon,char name)
{for (int i = 0; i < pcon->size; pcon->size++){if (strcmp(pcon->size,name)==0){return i;}}return -1;
}
先輸入用戶名,然后通過用戶名進行查找操作,找到了就調用順序表的刪除操作
void ContactDel(contact* pcon)
{printf("請輸入要刪除的用戶的名稱:\n");char name[NAME_MAX];scanf("%s", &name);int findidex = FindByName(pcon,name);SLPopBack(pcon);if (findidex < 0){printf("要刪除的聯系人不存在");return;}SLErase(pcon, findidex);
}
5.修改聯系人
通過查找,
void ContactModify(contact* pcon)
{printf("請輸入要修改的用戶名稱:\n");char name[NAME_MAX];scanf("%s", name);int find = FindByName(pcon, name);if (find < 0){printf("要修改的用戶不存在!\n");return;}printf("請輸入新的用戶名稱:\n");scanf("%s", pcon->a[find].name);printf("請輸入新的用戶性別:\n");scanf("%s", pcon->a[find].sex);printf("請輸入新的用戶年齡:\n");scanf("%s", pcon->a[find].age);printf("請輸入新的用戶電話:\n");scanf("%s", pcon->a[find].tel);printf("請輸入新的用戶地址:\n");scanf("%s", pcon->a[find].addr);printf("修改成功\n");
}
6.打印聯系人
void Contactshow(contact* pcon)
{printf("%s %s %s %s %s\n", "姓名", "性別", "年齡", "電話", "住址");for(int i = 0; i < pcon->size; i++){printf("%-4s %-4s %-4d %-4s %-4s\n",pcon->a[i].name,pcon->a[i].sex,pcon->a[i].age,pcon->a[i].tel,pcon->a[i].addr);}
}
7.查找聯系人
void ContactFind(contact* pcon)
{char name[NAME_MAX];printf("請輸入要查找的用戶名稱:\n");scanf("%s", name);int find = FindByName(pcon, name);if (find < 0){printf("該聯系人不存在\n");return;}printf("%s %s %d %s %s\n",pcon->a[find].name,pcon->a[find].sex,pcon->a[find].age,pcon->a[find].tel,pcon->a[find].addr);
}
完整代碼如下:
#define _CRT_SECURE_NO_WARNINGS 1
#include"SeqList.h"void ContactInit(contact* pcon)
{SLInit(pcon);
}
void ContactDestroy(contact* pcon)
{SLDestroy(pcon);
}void ContactAdd(contact** pcon)
{CInfo info;printf("請輸入聯系人的姓名:\n");scanf("%s", info.name);printf("請輸入聯系人的性別:\n");scanf("%s", info.sex);printf("請輸入聯系人的年齡:\n");scanf("%d", &info.age);printf("請輸入聯系人的電話:\n");scanf("%s", info.tel);printf("請輸入聯系人的住址:\n");scanf("%s", info.addr);SLPushBack(pcon, info);
}int FindByName(contact* pcon,char name)
{for (int i = 0; i < pcon->size; pcon->size++){if (strcmp(pcon->size,name)==0){return i;}}return -1;
}void ContactDel(contact* pcon)
{printf("請輸入要刪除的用戶的名稱:\n");char name[NAME_MAX];scanf("%s", &name);int findidex = FindByName(pcon,name);SLPopBack(pcon);if (findidex < 0){printf("要刪除的聯系人不存在");return;}SLErase(pcon, findidex);
}void ContactModify(contact* pcon)
{printf("請輸入要修改的用戶名稱:\n");char name[NAME_MAX];scanf("%s", name);int find = FindByName(pcon, name);if (find < 0){printf("要修改的用戶不存在!\n");return;}printf("請輸入新的用戶名稱:\n");scanf("%s", pcon->a[find].name);printf("請輸入新的用戶性別:\n");scanf("%s", pcon->a[find].sex);printf("請輸入新的用戶年齡:\n");scanf("%s", pcon->a[find].age);printf("請輸入新的用戶電話:\n");scanf("%s", pcon->a[find].tel);printf("請輸入新的用戶地址:\n");scanf("%s", pcon->a[find].addr);printf("修改成功\n");
}void Contactshow(contact* pcon)
{printf("%s %s %s %s %s\n", "姓名", "性別", "年齡", "電話", "住址");for(int i = 0; i < pcon->size; i++){printf("%-4s %-4s %-4d %-4s %-4s\n",pcon->a[i].name,pcon->a[i].sex,pcon->a[i].age,pcon->a[i].tel,pcon->a[i].addr);}
}void ContactFind(contact* pcon)
{char name[NAME_MAX];printf("請輸入要查找的用戶名稱:\n");scanf("%s", name);int find = FindByName(pcon, name);if (find < 0){printf("該聯系人不存在\n");return;}printf("%s %s %d %s %s\n",pcon->a[find].name,pcon->a[find].sex,pcon->a[find].age,pcon->a[find].tel,pcon->a[find].addr);
}
4SeqList.c
順序表的基本函數
此處存放順序表的基本操作函數,所以無需修改,與通訊錄有關的操作存放在Contact.c
文件中
#define _CRT_SECURE_NO_WARNINGS 1
#include"SeqList.h"void SLCheckCapacity(SL* ps) // 檢查內存是否足夠,不夠就擴容。
{if (ps->size == ps->capacity){int newCapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;SLDataType* tmp = (SLDataType*)realloc(ps->a, sizeof(SLDataType) * newCapacity);if (tmp == NULL){perror("realloc fail");return;}ps->a = tmp;ps->capacity = newCapacity;}
}void SLprintf(SL* ps) // 數據表打印
{for (int i = 0; i < ps->size; i++){printf("%d ", ps->a[i]);}printf("\n");
}void SLInit(SL* ps) // 數據表初始化
{assert(ps);ps->a = NULL;ps->size = 0;ps->capacity = 0;
}void SLDestroy(SL* ps) // 數據表銷毀
{assert(ps);if (ps->a != NULL){free(ps->a);ps->a = NULL;ps->size = 0;ps->capacity = 0;}
}void SLPushFront(SL* ps, SLDataType x) // 頭插
{assert(ps);SLCheckCapacity(ps);int end = ps->size - 1;while (end >= 0){ps->a[end + 1] = ps->a[end];end--;}ps->a[0] = x;ps->size++;
}void SLPushBack(SL* ps, SLDataType x) // 尾插
{assert(ps);SLCheckCapacity(ps);ps->a[ps->size++] = x;
}void SLPopFront(SL* ps) // 頭刪
{assert(ps);assert(ps->size > 0);int begin = 1;while (begin < ps->size){ps->a[begin - 1] = ps->a[begin];begin++;}ps->size--;
}void SLPopBack(SL* ps) // 尾刪
{assert(ps);assert(ps->size > 0);ps->size--;
}// pos是下標
void SLInsert(SL* ps, int pos, SLDataType x) // 任意下標位置的插入
{assert(ps);assert(pos >= 0 && pos <= ps->size);SLCheckCapacity(ps);int end = ps->size - 1;while (end >= pos){ps->a[end + 1] = ps->a[end];end--;}ps->a[pos] = x;ps->size++;
}
void SLErase(SL* ps, int pos) // 任意下標位置的刪除
{assert(ps);assert(pos >= 0 && pos < ps->size); // 這里刪除不能用等于ps->size,ps->size看作下標的話相當于下標的最后一個位置+1int begin = pos + 1;while (begin < ps->size){ps->a[begin - 1] = ps->a[begin];begin++;}ps->size--;
}