代码:
exper6.h文件
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
#include<assert.h>
#include<stdlib.h>
#define NAME_MAX 10
#define AGE_MAX 4
#define SEX_MAX 6
#define ADDR_MAX 20
#define TELE_MAX 12
#define QQ_MAX 12
#define EMAIL_MAX 20
#define DEFAULT_SZ 3
#define INC_SZ 2
typedef struct PeoInfo{
char name[NAME_MAX];
char age[AGE_MAX];
char sex[SEX_MAX];
char addr[ADDR_MAX];
char tele1[TELE_MAX];
char tele2[TELE_MAX];
char email[EMAIL_MAX];
char qq[QQ_MAX];
}PeoInfo;
typedef struct SSTable{
PeoInfo* data;
int sz;
int capacity;
}SSTable;
void Creat_Seq(SSTable* pc);
void DestroyContact(SSTable* pc);
void Insert_Seq(SSTable* pc);
void Delete_Seq(SSTable* pc);
void Print_Seq(const SSTable* pc);
void SearchContact(const SSTable* pc);
void Modify_Seq(SSTable* pc);
void EmptyContact(SSTable* pc);
void Sort_Seq(SSTable* pc);
void BinSearchContact(const SSTable* pc);
int BinFindByName(const SSTable* pc,char* name);
void menu();
void ReadFile(struct SSTable* pc);
void WriteFile(struct SSTable* pc);
text.c文件
#include"exper6.h"
int main(){
int swi = 0;
SSTable con;
Creat_Seq(&con);
do{
menu();
printf("请选择:>");
scanf("%d", &swi);
switch (swi){
case 1:
Insert_Seq(&con);break;
case 2:
Delete_Seq(&con);break;
case 3:
BinSearchContact(&con);break;
case 4:
Modify_Seq(&con);break;
case 5:
Print_Seq(&con);break;
case 6:
EmptyContact(&con);break;
case 7:
Sort_Seq(&con);break;
case 0:
WriteFile(&con);
DestroyContact(&con);
printf("退出程序:>\n");break;
default:
printf("输入非法,请重新输入!\n");break;
}
} while (swi);
return 0;
}
exper6.c文件
#include"exper6.h"
void Creat_Seq(SSTable* pc){
assert(pc);
pc->sz = 0;
PeoInfo* ptr = (PeoInfo*)calloc(DEFAULT_SZ, sizeof(PeoInfo));
if (ptr == NULL){
perror("Creat_Se::calloc");
return;
}
pc->data = ptr;
pc->capacity = DEFAULT_SZ;
ReadFile(pc);
}
void DestroyContact(SSTable* pc){
free(pc->data);
pc->data = NULL;
pc->capacity = 0;
pc->sz = 0;
pc = NULL;
}
void check_capacity(SSTable* pc){
if (pc->sz == pc->capacity){
PeoInfo* ptr = (PeoInfo*)realloc(pc->data, (pc->capacity + INC_SZ) * sizeof(PeoInfo));
if (ptr == NULL){
perror("check_capacity::realloc");
return;
}
pc->data = ptr;
pc->capacity += INC_SZ;
}
}
void Insert_Seq(SSTable* pc){
assert(pc);
check_capacity(pc);
while (1) {
printf("请输入联系人姓名:>");
scanf("%s", pc->data[pc->sz].name);
if (strlen(pc->data[pc->sz].name) >= NAME_MAX)
printf("您输入的姓名长度过长,请重新输入:>\n");
else
break;
}
while (1){
printf("请输入联系人年龄:>");
scanf("%s", pc->data[pc->sz].age);
if (strlen(pc->data[pc->sz].age) >= AGE_MAX)
printf("您输入的年龄过大,请重新输入:>\n");
else
break;
}
while (1){
printf("请输入联系人性别:>");
scanf("%s", pc->data[pc->sz].sex);
if (strlen(pc->data[pc->sz].sex) >= SEX_MAX)
printf("您输入的性别长度过长,请重新输入:>\n");
else
break;
}
while (1){
printf("请输入联系人地址:>");
scanf("%s", pc->data[pc->sz].addr);
if (strlen(pc->data[pc->sz].addr) >= ADDR_MAX)
printf("您输入的地址长度过长,请重新输入:>\n");
else
break;
}
while (1){
printf("请输入联系人电话1:>");
scanf("%s", pc->data[pc->sz].tele1);
if (strlen(pc->data[pc->sz].tele1) >= TELE_MAX)
printf("您输入的电话1长度过长,请重新输入:>\n");
else
break;
}
while (1){
printf("请输入联系人电话2:>");
scanf("%s", pc->data[pc->sz].tele2);
if (strlen(pc->data[pc->sz].tele2) >= TELE_MAX)
printf("您输入的电话2长度过长,请重新输入:>\n");
else
break;
}
while (1){
printf("请输入联系人电子邮箱:>");
scanf("%s", pc->data[pc->sz].email);
if (strlen(pc->data[pc->sz].email) >= EMAIL_MAX)
printf("您输入的电子邮箱长度过长,请重新输入:>\n");
else
break;
}
while (1){
printf("请输入联系人QQ号码:>");
scanf("%s", pc->data[pc->sz].qq);
if (strlen(pc->data[pc->sz].qq) >= QQ_MAX)
printf("您输入的QQ号码长度过长,请重新输入:>\n");
else
break;
}
pc->sz++;
printf("联系人信息添加成功:>\n");
}
void Delete_Seq(SSTable* pc){
assert(pc);
char name[NAME_MAX] = { 0 };
if (pc->sz == 0){
printf("通讯录为空,无法删除\n");
return;
}
printf("请输入要删除的联系人姓名:>");
scanf("%s", name);
int del = BinFindByName(pc, name);
if (-1 == del){
printf("抱歉,没有找到您要删除的联系人;<\n");
return;
}
int i = 0;
for (i = del; i < pc->sz - 1; i++){
pc->data[i] = pc->data[i + 1];
}
pc->sz--;
printf("联系人删除成功;>\n");
}
void Modify_Seq(SSTable* pc){
assert(pc);
char name[NAME_MAX] = { 0 };
printf("请输入要修改的联系人姓名:>");
scanf("%s", name);
int mod = BinFindByName(pc, name);
if (-1 == mod){
printf("抱歉,没有找到您要修改的联系人;<\n");
return;
}
printf("请输入修改后的联系人信息\n");
while (1){
printf("请输入联系人姓名:>");
scanf("%s", pc->data[mod].name);
if (strlen(pc->data[mod].name) >= NAME_MAX)
printf("您输入的姓名长度过长,请重新输入:>\n");
else
break;
}
while (1){
printf("请输入联系人年龄:>");
scanf("%s", pc->data[mod].age);
if (strlen(pc->data[mod].age) >= AGE_MAX)
printf("您输入的年龄过大,请重新输入:>\n");
else
break;
}
while (1){
printf("请输入联系人性别:>");
scanf("%s", pc->data[mod].sex);
if (strlen(pc->data[mod].sex) >= SEX_MAX)
printf("您输入的性别长度过长,请重新输入:>\n");
else
break;
}
while (1) {
printf("请输入联系人地址:>");
scanf("%s", pc->data[mod].addr);
if (strlen(pc->data[mod].addr) >= ADDR_MAX)
printf("您输入的地址长度过长,请重新输入:>\n");
else
break;
}
while (1) {
printf("请输入联系人电话1:>");
scanf("%s", pc->data[mod].tele1);
if (strlen(pc->data[mod].tele1) >= TELE_MAX)
printf("您输入的电话1长度过长,请重新输入:>\n");
else
break;
}
while (1) {
printf("请输入联系人电话2:>");
scanf("%s", pc->data[mod].tele2);
if (strlen(pc->data[mod].tele2) >= TELE_MAX)
printf("您输入的电话2长度过长,请重新输入:>\n");
else
break;
}
while (1) {
printf("请输入联系人电子邮箱:>");
scanf("%s", pc->data[mod].email);
if (strlen(pc->data[mod].email) >= EMAIL_MAX)
printf("您输入的电子邮箱长度过长,请重新输入:>\n");
else
break;
}
while (1){
printf("请输入联系人QQ号码:>");
scanf("%s", pc->data[mod].qq);
if (strlen(pc->data[mod].qq) >= QQ_MAX)
printf("您输入的QQ号码长度过长,请重新输入:>\n");
else
break;
}
printf("修改成功;>\n");
printf("____________________________________________________________________________________________________________________________________\n");
printf("%-4s\t%-10s\t%-4s\t%-6s\t%-20s\t%-12s\t%-12s\t%-20s\t%-12s\n", "|序号", "|姓名", "|年龄", "|性别", "|地址", "|电话1","|电话2","|电子邮箱","|QQ号码");
printf("____________________________________________________________________________________________________________________________________\n");
printf("|%-4d\t|%-10s\t|%-4s\t|%-6s\t|%-20s\t|%-12s\t|%-12s\t|%-20s\t|%-12s\n", mod + 1,
pc->data[mod].name,
pc->data[mod].age,
pc->data[mod].sex,
pc->data[mod].addr,
pc->data[mod].tele1,
pc->data[mod].tele2,
pc->data[mod].email,
pc->data[mod].qq);
printf("____________________________________________________________________________________________________________________________________\n");
}
void Print_Seq(const SSTable* pc){
assert(pc);
if (pc->sz == 0){
printf("通讯录为空,无法显示\n");
return;
}
int i = 0;
printf("____________________________________________________________________________________________________________________________________\n");
printf("%-4s\t%-10s\t%-4s\t%-6s\t%-20s\t%-12s\t%-12s\t%-20s\t%-12s\n", "|序号", "|姓名", "|年龄", "|性别", "|地址", "|电话1", "|电话2", "|电子邮箱", "|QQ号码");
for (i = 0; i < pc->sz; i++){
printf("____________________________________________________________________________________________________________________________________\n");
printf("|%-4d\t|%-10s\t|%-4s\t|%-6s\t|%-20s\t|%-12s\t|%-12s\t|%-20s\t|%-12s\n", i + 1,
pc->data[i].name,
pc->data[i].age,
pc->data[i].sex,
pc->data[i].addr,
pc->data[i].tele1,
pc->data[i].tele2,
pc->data[i].email,
pc->data[i].qq);
}
printf("____________________________________________________________________________________________________________________________________\n");
}
void EmptyContact(SSTable* pc){
assert(pc);
if (pc->sz == 0){
printf("通讯录为空,无需清空\n");
return;
}
pc->sz = 0;
memset(pc->data, 0, sizeof(pc->data));
printf("清空成功:>\n");
}
void ReadFile(SSTable* mm){
int i = 0;
FILE* pp = fopen("test.txt", "r");
if (NULL == pp){
perror("fopen()");
return;
}
while (fscanf(pp, "%[^,],%[^,],%[^,],%[^,],%[^,],%[^,],%[^,],%[^\n]\n",
&mm->data[i].name, &mm->data[i].age, &mm->data[i].sex, &mm->data[i].addr, &mm->data[i].tele1,&mm->data[i].tele2, &mm->data[i].email, &mm->data[i].qq) == 8)
{
i++;
mm->sz++;
check_capacity(mm);
}
fclose(pp);
pp = NULL;
}
void WriteFile(SSTable* mm){
int i = 0;
FILE* pp = fopen("test.txt", "w");
for (i = 0; i < mm->sz; i++) {
fprintf(pp, "%s,%s,%s,%s,%s,%s,%s,%s\n", mm->data[i].name, mm->data[i].age,
mm->data[i].sex, mm->data[i].addr, mm->data[i].tele1,
mm->data[i].tele2, mm->data[i].email, mm->data[i].qq);
}
fclose(pp);
pp = NULL;
}
int comper_name(const void* a, const void* b){
const PeoInfo* personA = (const PeoInfo*)a;
const PeoInfo* personB = (const PeoInfo*)b;
return strcmp(personA->name, personB->name);
}
int comper_age(const void* a, const void* b){
const PeoInfo* personA = (const PeoInfo*)a;
const PeoInfo* personB = (const PeoInfo*)b;
return strcmp(personA->age, personB->age);
}
int comper_sex(const void* a, const void* b){
const PeoInfo* personA = (const PeoInfo*)a;
const PeoInfo* personB = (const PeoInfo*)b;
return strcmp(personA->sex, personB->sex);
}
int comper_addr(const void* a, const void* b){
const PeoInfo* personA = (const PeoInfo*)a;
const PeoInfo* personB = (const PeoInfo*)b;
return strcmp(personA->addr, personB->addr);
}
void Swap(char* buf1, char* buf2, int sz){
int i = 0;
for (i = 0; i < sz; i++){
char tmp = *buf1;
*buf1 = *buf2;
*buf2 = tmp;
buf1++;
buf2++;
}
}
void Select_sort(void* base, size_t num, size_t sz, int(*compar)(const void*, const void*)){
int left = 0;
int right = num - 1;
while (left < right){
int mini = left, maxi = left;
for (int i = left + 1; i <= right; i++){
if (compar((char*)base + i * sz, (char*)base + (mini) * sz) < 0)
mini = i;
if (compar((char*)base + i * sz, (char*)base + (maxi) * sz) > 0)
maxi = i;
}
Swap((char*)base + left * sz, (char*)base + (mini) * sz, sz);
if (left == maxi)
maxi = mini;
Swap((char*)base + right * sz, (char*)base + (maxi) * sz, sz);
left++;
right--;
}
}
void Sort_Seq(SSTable* pc){
int cho = 0;
if (pc->sz == 0){
printf("通讯录为空,请先加入联系人\n");
return;
}
printf("*************************************\n");
printf("********1.按联系人姓名排序 *********\n");
printf("********2.按联系人年龄排序 *********\n");
printf("********3.按联系人性别排序 *********\n");
printf("********4.按联系人地址排序 *********\n");
printf("*************************************\n");
printf("请选择您想使用的排序方式:>");
scanf("%d", &cho);
int (*compare_func)(const void*, const void*) = NULL;
switch (cho){
case 1:
compare_func = comper_name;break;
case 2:
compare_func = comper_age;break;
case 3:
compare_func = comper_sex;break;
case 4:
compare_func = comper_addr;break;
default:
printf("排序选项无效:<\n");return;
}
Select_sort(pc->data, pc->sz, sizeof(PeoInfo), compare_func);
printf("排序成功:>\n");
Print_Seq(pc);
}
int BinFindByName(const SSTable* pc, char* name){
assert(pc);
Selecy_sort(pc->data, pc->sz, sizeof(PeoInfo), comper_name);
int low = 0;
int high = pc->sz - 1;
int mid;
while (low <= high){
mid = (low + high) / 2;
if (strcmp(pc->data[mid].name, name) == 0)
return mid;
else if (strcmp(pc->data[mid].name, name) > 0)
high = mid - 1;
else
low = mid + 1;
}
return -1;
}
void BinSearchContact(const SSTable* pc){
assert(pc);
char name[NAME_MAX] = { 0 };
printf("请输入要查找的联系人姓名:>");
scanf("%s", name);
int sea = BinFindByName(pc, name);
if (-1 == sea){
printf("抱歉,没有找到您要查找的联系人;<\n");
return;
}
printf("____________________________________________________________________________________________________________________________________\n");
printf("%-4s\t%-10s\t%-4s\t%-6s\t%-20s\t%-12s\t%-12s\t%-20s\t%-12s\n", "|序号", "|姓名", "|年龄", "|性别", "|地址", "|电话1", "|电话2", "|电子邮箱", "|QQ号码");
printf("____________________________________________________________________________________________________________________________________\n");
printf("|%-4d\t|%-10s\t|%-4s\t|%-6s\t|%-20s\t|%-12s\t|%-12s\t|%-20s\t|%-12s\n", sea + 1,
pc->data[sea].name,
pc->data[sea].age,
pc->data[sea].sex,
pc->data[sea].addr,
pc->data[sea].tele1,
pc->data[sea].tele2,
pc->data[sea].email,
pc->data[sea].qq);
printf("____________________________________________________________________________________________________________________________________\n");
}
void menu(){
printf("******************************************\n");
printf("*******请选择要进行的操作 *******\n");
printf("*******1.添加联系人信息 *******\n");
printf("*******2.删除联系人信息 *******\n");
printf("*******3.查找联系人信息 *******\n");
printf("*******4.修改联系人信息 *******\n");
printf("*******5.展示联系人信息 *******\n");
printf("*******6.清空联系人信息 *******\n");
printf("*******7.对联系人信息排序 *******\n");
printf("*******0.退出通讯录程序 *******\n");
printf("******************************************\n");
}
运行截图: