C语言——学生信息管理系统
概要
完成第一个小项目,学生信息管理系统
整体架构流程
实现增,删,改,查,四个操作
代码实现
- 必要准备:
typedef struct Student {
char name[20];
int age;
int class;
float height;
} Student;
#define MAX_ARR 10000
int stu_cnt = 0;
Student stu_arr[MAX_ARR + 5];
const char *file_name = "student_data.txt";
结构体的作用
数据封装:将学生的各项属性(名字、年龄、班级、身高)封装在一个结构体中,便于管理和操作。
代码简洁:通过结构体,可以避免单独定义多个变量来表示学生的各个属性,使代码更加简洁和易读。
数组管理:可以使用 Student 结构体数组来管理多个学生的数据,例如代码中的 stu_arr 数组。
文件读写:通过结构体数组,可以方便地将学生的数据写入文件或从文件中读取。
stu_cnt 记录数据个数。
stu_arr 记录用户数据。
- 主函数的建立:
int main() {
int n;
char s[100];
printf("Does the database exist?(是否存在数据库?) (y / n) : ");
scanf("%s", s);
printf("\n");
if(s[0] != 'y') {
printf("Please enter how many data items there are in total?(请输入共有多少项数据?) : ");
scanf("%d", &n);
printf("\n");
for (int i = 0; i < n; i++) {
create_file();
}
}
else {
stu_cnt = read_from_file(stu_arr);
}
while(1) {
int no = usage();
switch(no) {
case 1: student_list(); break;
case 2: student_add(); break;
case 3: student_modify(); break;
case 4: student_delete();break;
case 5: exit(0);
}
}
return 0;
}
引导用户创建数据库,并封装功能函数。
- create_file函数:
void create_file() {
FILE *fp = fopen(file_name, "w");
printf("add a new item : (name, age, class, height)\n");
printf("mysql > ");
scanf("%s%d%d%f",
stu_arr[stu_cnt].name, &stu_arr[stu_cnt].age, &stu_arr[stu_cnt].class, &stu_arr[stu_cnt].height
);
stu_cnt += 1;
fclose(fp);
output_arr_file(stu_arr, stu_cnt);
return ;
}
以写的方式打卡文件,如果没有就创建文件,并引导用户创建数据信息。
void output_arr_file(Student *arr, int n) {
FILE *fp = fopen(file_name, "a");
for (int i = 0; i < n; i++) {
fprintf(fp, "%s %d %d %.2f\n",
arr[i].name, arr[i].age, arr[i].class, arr[i].height
);
}
fclose(fp);
return ;
}
将数据信息以追加写的方式写入文件。
- read_from_file函数
int read_from_file(Student *arr) {
int i = 0;
FILE *fp = fopen(file_name, "r");
if (fp == NULL) return i;
while (fscanf(fp, "%s", arr[i].name) != EOF) {
fscanf(fp, "%d%d%f",
&arr[i].age, &arr[i].class, &arr[i].height
);
i += 1;
}
fclose(fp);
return i;
}
以读方式打开文件,读取文件数据返回值是数据个数。
- 交互界面:
int usage() {
int no;
do {
printf("1 : list students\n");
printf("2 : add a student\n");
printf("3 : modify a student\n");
printf("4 : delete a student\n");
printf("5 : quit\n", quit);
printf("mysql > ");
scanf("%d", &no);
} while (no < 1 || no > 5);
return no;
}
利用do{}while()
来保证用户输入的序号合法。
- student_list函数
void student_list() {
int n = printf("%4s|%10s|%5s|%6s|%7s|\n",
"id", "name", "age", "class", "height"
);
for (int i = 0; i < n; i++) {
printf("=");
}
printf("\n");
for (int i = 0; i < stu_cnt; i++) {
printf("%4d|%10s|%5d|%6d|%7.2f|\n",
i, stu_arr[i].name, stu_arr[i].age, stu_arr[i].class, stu_arr[i].height
);
}
printf("\n");
for (int i = 0; i < n; i++) {
printf("-");
}
printf("\n\n");
return ;
}
建立学生列表
- student_add函数
void student_add() {
FILE *fp = fopen(file_name, "a");
printf("add new item : (name, age, class, height)\n");
printf("mysql > ");
scanf("%s%d%d%f",
stu_arr[stu_cnt].name, &stu_arr[stu_cnt].age, &stu_arr[stu_cnt].class, &stu_arr[stu_cnt].height
);
fprintf(fp, "%s %d %d %.2f\n",
stu_arr[stu_cnt].name, stu_arr[stu_cnt].age, stu_arr[stu_cnt].class, stu_arr[stu_cnt].height
);
fclose(fp);
stu_cnt += 1;
int n = printf("add a astudent success!\n");
printf("\n");
for (int i = 0; i < n; i++) {
printf("-");
}
printf("\n\n");
return ;
}
添加学生信息
- student_modify函数
void student_modify() {
int id;
student_list();
do {
printf("modify id : ");
scanf("%d", &id);
} while (id < 0 || id >= stu_cnt);
printf("modify the item : (name, age, class, height)\n");
scanf("%s%d%d%f",
stu_arr[id].name, &stu_arr[id].age, &stu_arr[id].class, &stu_arr[id].height
);
restore_data_to_file(stu_arr, stu_cnt);
return ;
}
修改学生信息
void clear_arr_file() {
FILE *fp = fopen(file_name, "w");
fclose(fp);
return ;
}
void restore_data_to_file(Student *arr, int n) {
clear_arr_file();
output_arr_file(arr, n);
return ;
}
利用清空文件再重新写入的方式来更新数据信息
- student_delete函数
void student_delete() {
if (stu_cnt == 0) {
printf("There is no student.\n");
return ;
}
int id;
student_list();
do {
printf("delete id : ");
scanf("%d", &id);
} while (id < 0 || id >= stu_cnt);
printf("confirm (y / n) : ");
fflush(stdin);
char s[100];
scanf("%s", s);
if(s[0] != 'y') return ;
for (int i = id + 1; i < stu_cnt; i++) {
stu_arr[i - 1] = stu_arr[i];
}
stu_cnt -= 1;
restore_data_to_file(stu_arr, stu_cnt);
return ;
}
删除学生信息
代码优化
增加枚举类型来增加代码可读性。
enum NO_TYPE {
list = 1,
add,
modify,
del,
quit
};
int usage() {
int no;
do {
printf("%d : list students\n", list);
printf("%d : add a student\n", add);
printf("%d : modify a student\n", modify);
printf("%d : delete a student\n", del);
printf("%d : quit\n", quit);
printf("mysql > ");
scanf("%d", &no);
} while (no < 1 || no > 5);
return no;
}
int main() {
int n;
char s[100];
printf("Does the database exist?(是否存在数据库?) (y / n) : ");
scanf("%s", s);
printf("\n");
if(s[0] != 'y') {
printf("Please enter how many data items there are in total?(请输入共有多少项数据?) : ");
scanf("%d", &n);
printf("\n");
for (int i = 0; i < n; i++) {
create_file();
}
}
else {
stu_cnt = read_from_file(stu_arr);
}
while(1) {
int no = usage();
switch(no) {
case list: student_list(); break;
case add: student_add(); break;
case modify: student_modify(); break;
case del: student_delete();break;
case quit: exit(0);
}
}
return 0;
}
小结
在c语言的学习当中完成这个小项目,能让你的c语言能力更进一步。