您的位置:首页 > 其它

通讯录的实现

2021-04-11 14:17 78 查看

第一:实现要点

1.1 创建一个项目, 并创建相应的源代码和头文件

1.2. 定义数据结构类型到头文件:stu_info.h

1.2.1 学生结构体的成员:"name", "age", "tel", "height", "weight", "addr"
1.2.2 数据结构体的成员:struct STU stu[MAX];int num; // num:用来表示有多少个记录
1.2.3 定义一个枚举变量:用来存储选项的值:enum OPTIONS { EXIT, ADD, DELETE, MODIFY, SEARCH, SHOW, ORDER  };
1.2.4 函数的声明:。。。。

1.3 创建一个测试源代码文件:test.c,用于测试

里面包含一个main函数和所需要的的头文件

1.4 创建所用到的函数定义的源文件:stu_info.c

1.5 功能

(1)增、删、改、查、展示、排序(按照不同字段进行排序)
(2)保存结果
(3)再次运行时,会将保存的数据读入到数据中

1.6 用到的知识难点:

(1)数据类型:结构体和枚举变量
(2)函数参数:指针变量作为函数参数
(3)指针类型:指针数组(如成员列表)
(4)函数指针数组:void (*optp[7])(struct DATA*) = { save, add, del, modify, search, show, order };
(5)回调函数:在进行排序时,如:self_qsort(data->stu, data->num, LEN, sortp[ret]);

第二:各个源文件的代码清单

2.1 主函数|测试函数:test.c

#define _CRT_SECURE_NO_WARNINGS 1

#pragma once
#include "stu_info.h"

int main()
{
struct DATA data;
read_data(&data);
int input;
// 通过函数指针和回调函数的方式进行实现
void (*optp[7])(struct DATA*) = { save, add, del, modify, search, show, order };
do
{
menu();
scanf("%d", &input);
if (-1 < input && input < 7)
{
optp[input](&data);
}
else
{
printf("选择错误!\n");
}

} while (input);
// 通过switch语句的方式实现
//do
//{
//  menu();
//  scanf("%d", &input);
//  switch (input)
//  {
//  case ADD:
//      add(&data);
//      break;
//  case DELETE:
//      del(&data);
//      break;
//  case MODIFY:
//      modify(&data);
//      break;
//  case SEARCH:
//      search(&data);
//      break;
//  case SHOW:
//      show(&data);
//      break;
//  case ORDER:
//      order(&data);
//      break;
//  case EXIT:
//      save(&data);
//      printf("退出!");
//      break;
//  //  break;
//  default:
//      printf("Select Error!");
//      break;
//  }
//} while (input);

return 0;
}

2.2 头文件:stu_info.h

#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>

#define FILENAME "datafile"
#define MAX 1000
#define NAME_MAX 30
#define TEL_MAX 12
#define ADDR_MAX 40
// 定义一个枚举类型用来存储选择项
enum OPTIONS { EXIT, ADD, DELETE, MODIFY, SEARCH, SHOW, ORDER  };

struct STU
{
char name[NAME_MAX];
int age;
char tel[TEL_MAX];
double height;
double weight;
char addr[ADDR_MAX];
};

#define stu_elenum  6
// char name ; int age; char tel; double height;double weight;chr addr
struct DATA
{
struct STU stu[MAX];
int num;
};

#define LEN sizeof(struct STU)
// 函数声明

// 菜单函数声明
void menu();

// 数据保存到磁盘文件
void save(const struct DATA* data);

// 读取磁盘文件中的数据保存到data结构体中
void read_data(struct DATA* data);

// 增加数据
void add(struct DATA* data);

// 展示数据
void show(const struct DATA* data);

// 删除数据
void del(struct DATA* data);

// 删除数据
void modify(struct DATA* data);

// 查找数据
void search(const struct DATA* data);

// 排序数据
void order(const struct DATA* data);

2.3 函数实现源文件:stu_info.c

#define _CRT_SECURE_NO_WARNINGS 1

#include "stu_info.h"
char* stu_elelist[] = { "name", "age", "tel", "height", "weight", "addr" };

void menu()
{
printf("\n\n\n");
printf("\t\t|-------------------- Student grade system --------------------|\n");
printf("\t\t|                     0. exit                                  |\n");
printf("\t\t|                     1. add                                   |\n");
printf("\t\t|                     2. delete                                |\n");
printf("\t\t|                     3. modify                                |\n");
printf("\t\t|                     4. search                                |\n");
printf("\t\t|                     5. show                                  |\n");
printf("\t\t|                     6. order                                 |\n");
//printf("\t\t|                     7. show                                  |\n");
printf("\t\t|--------------------------------------------------------------|\n");
printf("\n\n\t\t\t\tplease select<0-7>:");
}

void save(const struct DATA* data)
{
int i;
FILE* fp;
fp = fopen(FILENAME, "wb");
if (NULL == fp)
{
printf("cannot open file: %s\n", FILENAME);
exit(0);
}
else
{
for (i = 0; i < data->num; i++)
{
if (fwrite(&data->stu[i], LEN, 1, fp) != 1)
{
printf("file write error!\n");
}
}
fclose(fp);
}
}

void read_data(struct DATA* data)
{
assert(data != NULL);
FILE* fp;
int i = 0;
fp = fopen(FILENAME, "rb");
if (NULL == fp)
{
printf("当前系统没有数据\n");
data->num = 0;
}
else
{
//printf("%d\n", feof(fp));
data->num = 0;
while (feof(fp) == 0)
{
if (fread(&data->stu[data->num], LEN, 1, fp) == 1)
{
data->num++;
}

}
fclose(fp);
}
}

void show(const struct DATA* data)
{
int i;
//char name; int age; char tel; double height; double weight; chr addr
printf("%-30s\t%-4s\t%-12s\t%-6s\t%-6s\t%-40s\n", "name", "age", "tel", "height", "weight", "addr");
for (i = 0; i < data->num; i++)
{
printf("%-30s\t%-4d\t%-12s\t%.2lf\t%.2lf\t%-40s\n",
data->stu[i].name,
data->stu[i].age,
data->stu[i].tel,
data->stu[i].height,
data->stu[i].weight,
data->stu[i].addr);
}
}

static void show_by_name(const struct DATA* data, int pos)
{
//char name; int age; char tel; double height; double weight; chr addr
printf("%-30s\t%-4s\t%-12s\t%-6s\t%-6s\t%-40s\n", "name", "age", "tel", "height", "weight", "addr");

printf("%-30s\t%-4d\t%-12s\t%.2lf\t%.2lf\t%-40s\n",
data->stu[pos].name,
data->stu[pos].age,
data->stu[pos].tel,
data->stu[pos].height,
data->stu[pos].weight,
data->stu[pos].addr);
}

// find:return pos in data->stu
// not find: return -1
static int find_data_by_name(const struct DATA* data, const char* name)
{
assert(data != NULL);
int i;
for (i = 0; i < data->num; i++)
{
if (strcmp(name, data->stu[i].name) == 0)
{
return i;
}
}
return -1;
}

static int find_name(const struct DATA* data, char* opty)
{
char name[NAME_MAX] = { 0 };
int pos = 0;
char choose = 0;
do
{
printf("please input the %s student's name:", opty);
scanf("%s", name);
pos = find_data_by_name(data, name);
if (-1 == pos)
{
printf("The student of %s not in the student information system.", name);
printf("Whether continue %s student record<y/n>:", opty);
getchar();
choose = getchar();
}
else
{
return pos;
}
} while (choose == 'y' || choose == 'Y');
return -1;
}

int sort_stu_by_name(const void* elem1, const void* elem2)
{
return strcmp(((struct STU*)elem1)->name, ((struct STU*)elem2)->name);
}

int sort_stu_by_age(const void* elem1, const void* elem2)
{
return ((struct STU*)elem1)->age - ((struct STU*)elem2)->age;
}

int sort_stu_by_tel(const void* elem1, const void* elem2)
{
return strcmp(((struct STU*)elem1)->tel, ((struct STU*)elem2)->tel);
}

int sort_stu_by_height(const void* elem1, const void* elem2)
{
if (((struct STU*)elem1)->height - ((struct STU*)elem2)->height > 1e-6)
return 1;
else if (((struct STU*)elem1)->height - ((struct STU*)elem2)->height < -1e-6)
return -1;
else
return 0;
}

int sort_stu_by_weight(const void* elem1, const void* elem2)
{
if (((struct STU*)elem1)->weight - ((struct STU*)elem2)->weight > 1e-6)
return 1;
else if (((struct STU*)elem1)->weight - ((struct STU*)elem2)->weight < -1e-6)
return -1;
else
return 0;
}

int sort_stu_by_addr(const void* elem1, const void* elem2)
{
return strcmp(((struct STU*)elem1)->addr, ((struct STU*)elem2)->addr);
}

void self_swap(char* buf1, char* buf2, int width)
{
int i;
char tmp;
for (i = 0; i < width; i++)
{
tmp = *buf1;
*buf1 = *buf2;
*buf2 = tmp;
buf1++;
buf2++;
}
}

void self_qsort(void* base, int num, int width, int (*pfunc)(const void* elem1, const void* elem2))
{
int i, j;
int flags;
for (i = 0; i < num - 1; i++)
{
flags = 1;
for (j = 0; j < num - 1 - i; j++)
{
if (pfunc((char*)base + j * width, (char*)base + (j + 1) * width) > 0)
{
flags = 0;
self_swap((char*)base + j * width, (char*)base + (j + 1) * width, width);
}

}
if (1 == flags)
{
break;
}
}
}

void add(struct DATA* data)
{
//char name; int age; char tel; double height; double weight; chr addr
char choose;
char name[NAME_MAX] = { 0 };
int dup = -1;
do
{
int num = data->num;
printf("input name:");
do
{
scanf("%s", name);
dup = find_data_by_name(data, name);
if (-1 == dup)
{
strcpy(data->stu[num].name, name);
break;
}
else
{
printf("The name of you input %s have existed, please renew input:", name);
}
} while (-1 != dup);

//scanf("%s", data->stu[num].name);
printf("input age:");
scanf("%d", &data->stu[num].age);
printf("input tel:");
scanf("%s", data->stu[num].tel);
printf("input height:");
scanf("%lf", &data->stu[num].height);
printf("input weight:");
scanf("%lf", &data->stu[num].weight);
printf("input addr:");
scanf("%s", data->stu[num].addr);
data->num++;
printf("whether continue add student?<y/n>");
//scanf("%s", choose);
getchar();
choose = getchar();
} while ('y' == choose || 'Y' == choose);
}

void del(struct DATA* data)
{
int pos = find_name(data, "delete");
int i;

if (-1 != pos)
{
char* name = data->stu[pos].name;
printf("The delete student's information:\n");
show_by_name(data, pos);
for (i = pos; i < data->num - 1; i++)
{
data->stu[i] = data->stu[i + 1];
}
printf("Delete Finish: %s\n", name);
data->num--;
}
}

void modify(struct DATA* data)
{
int pos = find_name(data, "modify");
if (-1 != pos)
{
printf("The modify student's information:\n");
show_by_name(data, pos);
//printf("modify name:");
//scanf("%s", data->stu[num].name);
printf("modify age:");
scanf("%d", &data->stu[pos].age);
printf("modify tel:");
scanf("%s", data->stu[pos].tel);
printf("modify height:");
scanf("%lf", &data->stu[pos].height);
printf("modify weight:");
scanf("%lf", &data->stu[pos].weight);
printf("modify addr:");
scanf("%s", data->stu[pos].addr);
printf("modify success!\n");
show_by_name(data, pos);
}
}

void search(const struct DATA* data)
{
int pos = find_name(data, "search");
if (-1 != pos)
{
printf("search success!\n");
show_by_name(data, pos);
}
}

void order(const struct DATA* data)
{
char choose[10];
char* info = "sort by: name | age | tel | height | weight | addr, please choose : ";
int ret = -1;
int i;
do
{
printf("%s", info);
scanf("%s", choose);
for (i = 0; i < stu_elenum; i++)
{
if (strcmp(choose, stu_elelist[i]) == 0)
{
ret = i;
break;
}
}
} while (-1 == ret);
int (*sortp[stu_elenum])(const void*, const void*) = { sort_stu_by_name ,sort_stu_by_age, sort_stu_by_tel, sort_stu_by_height, sort_stu_by_weight, sort_stu_by_addr };
self_qsort(data->stu, data->num, LEN, sortp[ret]);
}

第三:功能展示

部分功能展示:

3.1 菜单展示:

3.2 数据展示:

3.3 修改展示:

3.4 排序展示:


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: