通讯录的实现
第一:实现要点
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 addrstruct 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 -1static 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]); }
第三:功能展示
部分功能展示: