基于动态顺序表,预先开辟一个小的空间,在后续的使用中,如果空间不够,则重新开辟空间,将数据更新到新开辟的空间中。
最后将通讯录内容按顺序保存在文件 Contact.txt 中,供用户打开通讯录。
//addr_D.h
#pragma once
#pragma warning (disable:4996)
#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#define MAX_NAME 200
#define MAX_PHONE 200
#define MAX_ADDRESS 200
#define FILE_PATH "Contact.txt"
//定义通讯录信息,此处仅包含姓名,电话号码,地址
typedef struct Contact_D
{
char name[MAX_NAME];
char phone[MAX_PHONE];
char address[MAX_ADDRESS];
}Contact_D;
typedef struct addrbook_D
{
Contact_D *data;
size_t size;
size_t capacity;
}addrbook_D;
void addrInit_D(addrbook_D *addr);//初始化通讯录
void addrPrint_D(addrbook_D *addr);//打印通讯录
void addrInsert_D(addrbook_D *addr);//插入联系人
void addrDelect_D(addrbook_D *addr);//删除联系人
size_t addrSearch_forname_D(addrbook_D *addr);//按照姓名查找联系人
void addrSearch_forphone_D(addrbook_D *addr);//按照电话号码查找联系人
void addrUpdate_D(addrbook_D *addr);//修改联系人信息
void addrDestory_D(addrbook_D *addr);//清空通讯录
//文件管理
void addrsave_D(addrbook_D *addr);//将通讯录保存在文件中
void addrLoad_D(addrbook_D *addr);//将文件中的通讯录加载在内存中
//addrbook_D.c
#include "addr_D.h"
//初始化通讯录
void addrInit_D(addrbook_D *addr)
{
if (addr == NULL)
{
printf("addr_book is null...\n");
return;
}
addr->size = 0;
addr->capacity = 1;
addr->data = (Contact_D *)malloc(sizeof(Contact_D)*addr->capacity);//预先开辟小的空间,为加速插入联系人
}
//姓名ASCII大的交换到后方
void Swap(Contact_D *a, Contact_D *b)
{
Contact_D tmp = *a;
*a = *b;
*b = tmp;
}
//冒泡排序给通讯录排序
void bubble_sort(addrbook_D *addr)
{
if (addr == NULL)
{
printf("addr_book is null...\n");
return;
}
size_t i = 0;
size_t j = 0;
for (; i < addr->size - 1; i++)
{
for (j = 0; j < addr->size - i - 1; j++)
{
if (strcmp(addr->data[j].name, addr->data[j + 1].name)==1)
Swap(&(addr->data[j]), &(addr->data[j + 1]));
}
}
}
//打印通讯录
void addrPrint_D(addrbook_D *addr)
{
if (addr == NULL)
{
printf("addr_book is null...\n");
return;
}
bubble_sort(addr);
size_t i = 0;
printf("\t姓名 \t\t电话 \t\t\t地址\t\n");
printf("-------------------------------------------------------\n");
for (; i < addr->size; i++)
{
printf("%lu\t%s \t\t%s \t\t%s \t\n", i + 1, addr->data[i].name, addr->data[i].phone, addr->data[i].address);
}
printf("\n共有 %lu 位联系人\n\n", addr->size);
}
//若当前内存不够,则重新申请内存
void addr_D_relloc(addrbook_D* addr)
{
if (addr == NULL)
{
printf("addr_book is null...\n");
return;
}
addr->capacity = 2 * addr->capacity + 1;
Contact_D *new_data_D = (Contact_D *)malloc(sizeof(Contact_D)*addr->capacity);
size_t i = 0;
for (; i < addr->size; i++)
{
new_data_D[i] = addr->data[i];
}
free(addr->data);
addr->data = new_data_D;
}
//插入联系人
void addrInsert_D(addrbook_D *addr)
{
if (addr == NULL)
{
printf("addr_book is null...\n");
return;
}
if (addr->size >= addr->capacity)
addr_D_relloc(addr);
printf("请输入联系人信息:[姓名] [电话] [住址]\n");
scanf("%s%s%s", addr->data[addr->size].name, addr->data[addr->size].phone, addr->data[addr->size].address);
addr->size++;
printf("插入成功\n");
}
//删除联系人
void addrDelect_D(addrbook_D *addr)
{
if (addr == NULL)
{
printf("addr_book is null...\n");
return;
}
addrPrint_D(addr);
size_t i = 0;
printf("请输入要删除联系人的编号: ");
scanf("%lu", &i);
for (i--; i < addr->size - 1; i++)
{
addr->data[i] = addr->data[i + 1];
}
addr->size--;
}
//按照姓名查找联系人
size_t addrSearch_forname_D(addrbook_D *addr)
{
if (addr == NULL)
{
printf("addr_book is null...\n");
return (size_t)-1;
}
char name[200];
printf("请输入要查找的姓名 : ");
scanf("%s", name);
size_t i = 0;
for (; i < addr->size; i++)
{
if (strcmp(name, addr->data[i].name) == 0)
{
printf("%s\t%s\t%s\n", addr->data[i].name, addr->data[i].phone, addr->data[i].address);
return i;
}
}
printf("没有找到联系人\n");
return (size_t)-1;
}
//按照电话号码查找联系人
void addrSearch_forphone_D(addrbook_D *addr)
{
if (addr == NULL)
{
printf("Addr is NULL...\n");
return;
}
char num[200];
printf("请输入要查找的电话号码:");
scanf("%s", num);
size_t i = 0;
size_t count = 0;
for (; i < addr->size; i++)
{
if (strstr(addr->data[i].phone, num) != NULL)
{
printf("%s\t%s\t%s\n", addr->data[i].name, addr->data[i].phone, addr->data[i].address);
count++;
}
}
if (count == 0)
printf("没有找到该号码\n");
return;
}
//修改联系人信息
void addrUpdate_D(addrbook_D *addr)
{
if (addr == NULL)
{
printf("Addr is NULL...\n");
return;
}
size_t pos = addrSearch_forname_D(addr);
if (pos > addr->size)
{
printf("查找联系人失败\n");
return;
}
printf("请选择要修改的信息(1.姓名 2.电话 3.地址)");
size_t choose;
scanf("%lu", &choose);
if (choose == 1)
{
printf("请输入新的姓名:");
scanf("%s", addr->data[pos].name);
}
else if (choose == 2)
{
printf("请输入新的电话号码:");
scanf("%s", addr->data[pos].phone);
}
else if (choose == 3)
{
printf("请输入新的地址:");
scanf("%s", addr->data[pos].address);
}
else
printf("输入有误\n");
return;
}
//清空通讯录
void addrDestory_D(addrbook_D *addr)
{
if (addr == NULL)
return;
addr->size = 0;
addr->capacity = 0;
free(addr->data);
}
//
//文件管理
//
//将通讯录保存在文件中
void addrsave_D(addrbook_D *addr)
{
if (addr == NULL)
{
printf("Addr is NULL...\n");
return;
}
FILE *fp = fopen(FILE_PATH, "w");
if (fp == NULL)
{
printf("打开文件失败! %s\n", FILE_PATH);
return;
}
bubble_sort(addr);
size_t i = 0;
for (; i < addr->size; i++)
{
fprintf(fp, "%s\t%s\t%s\n", addr->data[i].name, addr->data[i].phone, addr->data[i].address);
}
fclose(fp);
}
//将通讯录内容加载在内存中
void addrLoad_D(addrbook_D *addr)
{
if (addr == NULL)
{
printf("Addr is NULL...\n");
return;
}
FILE *fp = fopen(FILE_PATH, "r");
if (fp == NULL)
{
printf("文件打开失败! %s\n", FILE_PATH);
}
while (!feof(fp))
{
if (addr->size >= addr->capacity)
addr_D_relloc(addr);
fscanf(fp, "%s\t%s\t%s\n", addr->data[addr->size].name,
addr->data[addr->size].phone,
addr->data[addr->size].address );
addr->size++;
}
}
//test.c
#include "addr_D.h"
//菜单
void menu()
{
addrbook_D addr_D;
addrInit_D(&addr_D); //预先初始化通讯录
addrLoad_D(&addr_D); //加载文件Contact.cde 内容到内存中
while (1)
{
printf("************************************************************\n");
printf("** 1.添加 2.删除 3查找 4.修改 5.打印 0.清空 **\n");
printf("************************************************************\n");
size_t input;
printf("Please Choose : ");
scanf("%lu", &input);
switch (input)
{
case 1:
addrInsert_D(&addr_D);
addrsave_D(&addr_D);
break;
case 2:
addrDelect_D(&addr_D);
addrsave_D(&addr_D);
break;
case 3:
{
size_t choose = 0;
printf("请选择查找方式(姓名 :1 电话 :2) : ");
scanf("%lu", &choose);
switch (choose)
{
case 1: addrSearch_forname_D(&addr_D);
break;
case 2: addrSearch_forphone_D(&addr_D);
break;
default:
break;
}
break;
}
case 4:
addrUpdate_D(&addr_D);
addrsave_D(&addr_D);
break;
case 5:
addrPrint_D(&addr_D);
//addrsave_D(&addr_D);
break;
case 0:
break;
default:
break;
}
}
}
int main()
{
menu();
system("pause");
return 0;
}
将文件加载到内存
插入一个联系人
删除一位联系人
修改联系人信息
查找联系人
当前文件信息