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 函数的声明:。。。。
里面包含一个main函数和所需要的的头文件
(1)增、删、改、查、展示、排序(按照不同字段进行排序)
(2)保存结果
(3)再次运行时,会将保存的数据读入到数据中
(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]);
#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;
}
#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);
#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]);
}
部分功能展示:
原文:https://blog.51cto.com/u_15132389/2698903