很久以前我们软件工程老师用这个项目设计当做我们的期末作业

当时也是设计了很长时间,最后得了很高的分数,当时记得很激动

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
#include <stdio.h>
#include <stdlib.h> // system()函数需要引用stdlib.h头文件
#include <string.h> // 字符串函数需要引用string.h头文件
#include <ctype.h>

#define MAX_STUDENTS 30 // 最大学生人数

//定义学生数据存储位置,比如我就放到D盘的"数据库.txt"文件里
#define FILE_PATH "D:\\数据库.txt"
//TXT用UTF-8格式,编译器也设置为UTF-8打开,不然中文全是乱七八糟的字符

struct Student {
char name[30]; // 姓名
long long id; // 学号
float score; // 成绩
};

//原本的程序输出的时候输出语句都靠的太近了所以代码中加了很多printf("\n");语句

// 为了方便检测学生的学号重叠问题,新定义一个checkIdExists函数检查学号是否已存在
int checkIdExists(struct Student students[], int count, int id) {
for (int i = 0; i < count; i++) {
if (students[i].id == id) {
return 1; // 学号已存在
}
}
return 0; // 学号不存在
}


//输入学生信息函数
void inputStudent(struct Student students[], int *count) {

int newCount;
printf("请问要录入几个学生呢?\n");
printf("人数:");
scanf("%d", &newCount);

// 计算总共会有多少学生
int total = *count + newCount;

//判断输入人数是否合理 ,下面的插入学生函数也做了相同的判断
if (total > MAX_STUDENTS) {
int canAdd = MAX_STUDENTS - *count;
printf("对不起哦,您最多只能再录入 %d 个人(总共不能超过 %d 人)\n", canAdd, MAX_STUDENTS);
// 询问用户是否要继续录入可添加的数量
printf("是否录入 %d 个学生?(1. 是 / 0. 否): ", canAdd);
int choice;
scanf("%d", &choice);
if (choice != 1) {
return;
}
newCount = canAdd;
}

// 从当前学生数开始录入新学生
for (int i = *count; i < *count + newCount; i++) {
printf("\n");
printf("第%d个学生\n", i + 1 - *count);
//这里因为地球上有一堆人同名同姓,所以允许学生名字相同但学号必须唯一
printf("姓名:");
scanf("%s", students[i].name);

//确保学号为10位及以下
while (1) {
printf("学号:");
//先判断学号是否10位及以下
if (scanf("%lld", &students[i].id) != 1 || students[i].id < 0 || students[i].id > 9999999999) {
printf("学号无效(学号必须是最多10位的数字),请重新输入。\n");
while (getchar() != '\n');
} else if (checkIdExists(students, i, students[i].id)) {
//再调用checkIdExists判断学号是否重复
printf("学号 %lld 已存在,请重新输入哦\n", students[i].id);
} else {
//两种情况都不存在的话就跳出while循环
break;
}
}

//确保成绩0~750
while (1) {
printf("成绩:");
//逻辑和 确保学号为10位及以下 一模一样
if (scanf("%f", &students[i].score) != 1 || students[i].score < 0 || students[i].score > 750) {
printf("成绩无效(成绩必须在0到750之间),请重新输入哦。\n");
while (getchar() != '\n');
} else {
break;
}
}
}

// 更新学生总数
*count += newCount;
printf("\n成功录入 %d 名新学生!当前总共 %d 名学生。\n", newCount, *count);

}

//显示所有学生信息
void printAllStudents(struct Student students[], int count) {
//如果没有一个学生
if (count == 0) {
printf("当前系统没有学生哦。\n");
return;
}
//for循环遍历
for (int i = 0; i < count; i++) {
printf("姓名:%s 学号:%lld 成绩:%.2f\n", students[i].name, students[i].id, students[i].score);
}
}

// 查找学生信息函数
void searchStudent(struct Student students[], int count) {

//如果没有一个学生
if (count == 0) {
printf("当前系统没有学生哦。\n");
return;
}

int choice;
printf("请选择查找方式:\n");
printf("1. 按姓名查找\n");
printf("2. 按学号查找\n");
printf("请输入选项:");
scanf("%d", &choice);

switch (choice) {
case 1: {
// 按姓名查找
char name[30];
printf("请输入学生姓名:");
scanf("%s", name);
//使用found来定义学生的存在状态 0不存在,1存在
int found = 0;
for (int i = 0; i < count; i++) {
//用strcmp将学生姓名一一对比,如果找到就跳出循环
if (strcmp(students[i].name, name) == 0) {
printf("\n找到啦!\n");
printf("姓名:%s 学号:%lld 成绩:%.2f\n", students[i].name, students[i].id, students[i].score);
found = 1;
break;
}
}
//找不到就输出找不到
if (!found) {
printf("没有找到该同学诶。\n");
break;
}
break;
}

case 2: {
// 按学号查找
int id;
printf("请输入学生学号:");
scanf("%d", &id);

int found = 0;

for (int i = 0; i < count; i++) {
//和刚才的姓名查找逻辑一模一样,只是把结构体成员由name改为id
if (students[i].id == id) {
printf("\n找到啦!\n");
printf("姓名:%s 学号:%lld 成绩:%.2f\n", students[i].name, students[i].id, students[i].score);
found = 1;
break;
}
}
//没找到就是没找到
if (!found) {
printf("没有找到该同学诶。\n");
break;
}
break;
}
//如果不满足前两个case条件,就输出default
default:
printf("无效的选项,您只能输入1或者2哦。\n");
}
}


// 删除学生信息函数
void deleteStudent(struct Student students[], int *count) {
//如果没有一个学生
if (*count == 0) {
printf("当前系统没有学生哦。\n");
return;
}

int choice;
printf("请选择删除方式:\n");
printf("1. 按姓名删除\n");
printf("2. 按学号删除\n");
printf("请输入选项:");
scanf("%d", &choice);
//这里之所以让index=-1而不是0是因为还有一种情况,就是删除前先要通过姓名和学号来查找学生
//如果输入了一个不存在的名字或学号,就要给出"找不到"的提示
//也就是说,前面的查找函数在这里又用了一下
int index = -1;
switch (choice) {
case 1: {
// 按姓名删除
char name[30];
printf("请输入学生姓名:");
scanf("%s", name);
//删除的逻辑和 上面查找函数一模一样,就是找到这个同学,然后删了他,只是定义了一个index=-1的区别
//因为如果定义index为0或者正数,就会影响下面for循环的使用 ,所以随便定义一个负数比如-1就可以了
for (int i = 0; i < *count; i++) {
if (strcmp(students[i].name, name) == 0) {
//找到了就将index改为当前的学生数组的索引
index = i;
break;
}
}
//找不到就跳出
break;
}


case 2: {
// 按学号删除
int id;
printf("请输入学生学号:");
scanf("%d", &id);
//和姓名删除一模一样
for (int i = 0; i < *count; i++) {
if (students[i].id == id) {
index = i;
break;
}
}
break;
}
//如果输入其他数字就提醒一下
default:
printf("无效的选项,您只能输入1或者2哦。\n");
return;
}
//只要姓名和学号找不到,而代码在函数内从上往下执行 ,就一定会对index的值进行判断
//然后提醒没有这个同学信息
if (index == -1) {
printf("没有找到该同学诶。\n");
return;
}

// 确认删除
int confirm;
for (int i = 0; i < 3; i++) {
//为防止不小心删错了,所以用for循环搞一个确认三遍
// validInput用于检测输入是否有效,因为我发现输入0和1以外的数字会退出删除操作,所以强制规范一下
int validInput = 0;

while (!validInput) {
printf("确定要删除该学生信息吗?需要您确认三遍才行哦(1. 确定 / 0. 取消):");
if (scanf("%d", &confirm) == 1 && (confirm == 0 || confirm == 1)) {
validInput = 1; // 如果输入有效,就是要么是0,要么是1,就退出循环
} else {
printf("无效的输入,您只能输入0或者1哦\n");
while (getchar() != '\n'); // 清空输入缓冲区
}
}
if (confirm != 1) {
printf("删除操作已取消。\n");
return;
}
}

// 删除学生信息
//这里删除之后调整一下学生索引的位置
//就是继承原先数组学生的顺序,因为删了一个,新数组又少一个位子,所以被删的学生的索引位子会被下一个学生顶替
for (int i = index; i < *count - 1; i++) {
students[i] = students[i + 1];
}
//删除后将学生总数减一
(*count)--;
printf("该同学信息已删除!\n");
}

// 修改学生信息函数
void modifyStudent(struct Student students[], int count) {
//如果没有一个学生
if (count == 0) {
printf("当前系统没有学生哦。\n");
return;
}

int choice;
printf("选择修改方式:\n");
printf("1. 按姓名修改\n");
printf("2. 按学号修改\n");
printf("请输入选项:");
scanf("%d", &choice);
//修改的话和删除差不多(指的是前期都是通过按姓名或学号先找到学生,然后修改)

//以下部分就是直接套用上面删除函数的逻辑
int index = -1;
switch (choice) {
case 1: {
// 按姓名修改
char name[30];
printf("请输入要修改的学生的姓名:");
scanf("%s", name);

for (int i = 0; i < count; i++) {
if (strcmp(students[i].name, name) == 0) {
index = i;
break;
}
}
break;
}

case 2: {
// 按学号修改
int id;
printf("请输入要修改的学生的学号:");
scanf("%d", &id);

for (int i = 0; i < count; i++) {
if (students[i].id == id) {
index = i;
break;
}
}
break;
}

default:
printf("无效的选项,您只能输入1或者2哦。\n");
return;
}

if (index == -1) {
printf("没有找到该同学诶。\n");
return;
}

printf("\n找到啦!这是该同学的信息!:\n");
printf("姓名:%s 学号:%lld 成绩:%.2f\n", students[index].name, students[index].id, students[index].score);
//找到后就是修改这个同学的信息
int modifyChoice;
printf("\n请问您要修改他/她的什么信息呢:\n");
printf("1. 修改姓名\n");
printf("2. 修改学号\n");
printf("3. 修改成绩\n");
printf("请输入选项:");
scanf("%d", &modifyChoice);

// 存储原始值,以便在取消修改时恢复
struct Student original = students[index];

//因为不知道到底改什么信息,所以用switch case语句问一下 要改哪个
switch (modifyChoice) {
case 1: {
// 修改姓名
printf("请输入新的姓名:");
scanf("%s", students[index].name);
break;
}

case 2: {
// 修改学号
//和case1逻辑一模一样
printf("请输入新的学号:");
scanf("%lld", &students[index].id);
break;
}

case 3: {
// 修改成绩
//和case1逻辑一模一样
printf("请输入新的成绩:");
scanf("%f", &students[index].score);
break;
}
//就三个选项,要是输入了其他的只能default提醒一下输错了
default:
printf("无效的选项,您只能输入1或者2或者3哦。\n");
return;
}

//同样为防止不小心误改,改之后确认一下
//这里的逻辑和删除函数里确认删不删逻辑一样
// 统一确认操作(只需一次确认)
int confirm;
int validInput = 0;// 用于检测输入是否有效
while (!validInput) {
printf("确定要修改学生信息吗?(1. 确定 / 0. 取消):");

if (scanf("%d", &confirm) == 1 && (confirm == 0 || confirm == 1)) {
validInput = 1;// 如果输入有效,退出循环
} else {
printf("无效的输入,您只能输入0或者1哦\n");
while (getchar() != '\n');// 清空输入缓冲区
}
}

if (confirm != 1) {
// 取消修改,恢复原始值
students[index] = original;
printf("修改操作已取消。\n");
return;
}

printf("学生信息已修改。\n");
printf("这是他/她修改后的学生信息哦:\n");
//这里打印一下学生信息看看有没有改错
printf("姓名:%s 学号:%lld 成绩:%.2f\n", students[index].name, students[index].id, students[index].score);
}

// 插入学生信息函数
void insertStudent(struct Student students[], int *count) {
//和输入学生信息函数的逻辑一样,要保证学生的数量再合理范围内
if (*count >= MAX_STUDENTS) {
printf("学生信息已满(限定 %d 个),无法插入新学生。\n",MAX_STUDENTS);
return;
}
//提醒一下现在要插入第几个学生以及总共可以有多少个学生
printf("总共可以插入 %d 个学生,当前已有 %d 个学生,您将插入第 %d 个学生的信息哦!\n",MAX_STUDENTS, *count, *count + 1);

//以下内容逻辑和录入学生信息函数逻辑一模一样 ,就不重复解释了
printf("请输入新学生的姓名:");
scanf("%s", students[*count].name);

while (1) {
printf("请输入新学生的学号:");
if (scanf("%lld", &students[*count].id) != 1 || students[*count].id < 0 || students[*count].id > 9999999999) {
printf("学号无效(学号必须是最多10位的数字),请重新输入。\n");
while (getchar() != '\n'); // 清空输入缓冲区
} else if (checkIdExists(students, *count, students[*count].id)) {
printf("学号 %lld 已存在,您看看是不是输错了?请重新输入哦\n", students[*count].id);
} else {
break;
}
}

while (1) {
printf("请输入新学生的成绩:");
if (scanf("%f", &students[*count].score) != 1 || students[*count].score < 0 || students[*count].score > 750) {
printf("成绩无效(成绩必须在0到750之间),请重新输入哦。\n");
while (getchar() != '\n'); // 清空输入缓冲区
} else {
break;
}
}


(*count)++;
printf("\n新学生信息已插入!这是他/她的信息哦\n");
printf("姓名:%s 学号:%lld 成绩:%.2f\n", students[*count - 1].name, students[*count - 1].id, students[*count - 1].score);
}

//下面如果用冒泡排序,选择排序或插入排序比较浪费时间,如果有几十个学生还好
//要是成千上百个这种方法效率低下,所以我用快速排序

// 快速排序的辅助函数,用于交换两个学生的信息
void swap(struct Student *a, struct Student *b) {
struct Student temp = *a;
*a = *b;
*b = temp;
}

// 快速排序的辅助函数,用于分区
int partition(struct Student students[], int low, int high) {
//因为是按学生成绩score进行排名,所以用 students[].score
float pivot = students[high].score;
int i = (low - 1);

for (int j = low; j <= high - 1; j++) {
if (students[j].score > pivot) {
i++;
//调用swap函数快速将学生交换
swap(&students[i], &students[j]);
}
}
swap(&students[i + 1], &students[high]);
return (i + 1);
}

// 快速排序函数
void quickSort(struct Student students[], int low, int high) {
if (low < high) {
int pi = partition(students, low, high);

quickSort(students, low, pi - 1);
quickSort(students, pi + 1, high);
}
}

// 根据成绩排序并显示排名
void rankStudents(struct Student students[], int count) {

//如果当前系统没有学生的话
if (count == 0) {
printf("当前系统没有学生哦。\n");
return;
}
//调用quickSort函数对学生成绩进行降序排序
quickSort(students, 0, count - 1);

//打印排序后的学生信息
printf("这是同学们的考试成绩排名哦:\n");
//遍历打印学生按成绩排名的信息
for (int i = 0; i < count; i++) {
printf(" 第%d名: 姓名:%s 学号:%lld 成绩:%.2f\n", i + 1, students[i].name, students[i].id, students[i].score);
}
}

// 统计学生总数
void countStudents(int count) {
printf("当前一共有:%d个学生哦\n", count);
}

// 清屏函数
void clearScreen() {
// 判断操作系统并执行相应的命令
#ifdef _WIN32 // Windows 系统
system("cls");
#else // Linux / macOS 系统
system("clear");
#endif
}


//清空缓冲区函数
void clearInputBuffer() {
// 清空缓冲区直到换行符或文件结束符
int c;
while ((c = getchar()) != '\n' && c != EOF) {}
}

// 退出系统确认函数
//因为我发现把这个功能写进主函数时程序比较卡,只能单独弄一个函数 ,然后再定义一个clearInputBuffer函数清除一下缓存
int confirmExit() {

//确认的方法和前面使用的差不多
int confirm;

for (int i = 0; i < 3; i++) {
int validInput = 0;
while (!validInput) {
//这里用了两个三元运算符
//三元运算符的执行顺序是从左到右的
//先判断第一个条件,如果条件为真,则返回第一个结果;如果条件为假,则继续评估下一个条件
printf("%s", (i == 0) ? "真的要退出系统吗亲 (1. 确定退出 / 0. 取消操作):"
: (i == 1) ? "要不要再检查一下亲 (1. 确定退出 / 0. 取消操作):"
: "确认信息无误就可以退出咯 (1. 确定退出 / 0. 取消操作):");
if (scanf("%d", &confirm) == 1 && (confirm == 0 || confirm == 1)) {
validInput = 1;
} else {
printf("无效的输入,您只能输入0或者1哦\n");
clearInputBuffer(); // 清空输入缓冲区
}
}
if (confirm == 0) {
printf("取消操作。\n");
return 0; // 返回0表示取消退出
}
}
return 1; // 返回1表示确认退出
}

// 保存学生信息到文件
void saveStudentsToFile(struct Student students[], int count) {
//写入文件信息
FILE *file = fopen(FILE_PATH, "w");
//出现异常时
if (file == NULL) {
perror("无法打开文件");
return;
}
//循环遍历输入信息到文件中
for (int i = 0; i < count; i++) {
fprintf(file, "姓名:%s 学号:%lld 成绩:%.2f\n", students[i].name, students[i].id, students[i].score);
}
//停止写入
fclose(file);
printf("学生信息已保存到文件 %s\n", FILE_PATH);
}

// 从文件加载学生信息
void loadStudentsFromFile(struct Student students[], int *count) {
//读取文件信息
FILE *file = fopen(FILE_PATH, "r");
//判断一下这玩意在不在
if (!file) {
printf("文件 %s 不存在,将创建新文件\n", FILE_PATH);
return;
}

// 初始化学生计数为0
*count = 0;
// 创建缓冲区line用于存储文件中的一行内容
char line[256];


// 逐行读取文件内容,直到文件结束或达到最大学生数
while (fgets(line, sizeof(line), file) && *count < MAX_STUDENTS) {
// 定位关键字段
// 在行中定位"姓名:","学号:","成绩:"这三个关键字段的位置
char *name_start = strstr(line, "姓名:");
char *id_start = strstr(line, "学号:");
char *score_start = strstr(line, "成绩:");

// 检查这一行是否所有关键字段都存在
if (!name_start || !id_start || !score_start){
// 只要缺一个就跳过这个的学生信息
continue;
}


// 提取姓名,姓名为字符串类型所以需要特殊处理
name_start += strlen("姓名:");
// 计算姓名长度:从"姓名:"开始到"学号:"结束之间
int name_len = id_start - name_start - 2; // 减去两个空格

// 检查姓名长度是否有效(大于0且小于结构体中姓名字段的最大长度)
if (name_len > 0 && (size_t)name_len < sizeof(students[*count].name)) {
// 复制姓名到学生结构体
strncpy(students[*count].name, name_start, name_len);
// 确保姓名字符串正确终止
students[*count].name[name_len] = '\0';
}

// 提取学号和成绩
sscanf(id_start + strlen("学号:"), "%lld", &students[*count].id);
sscanf(score_start + strlen("成绩:"), "%f", &students[*count].score);

// 成功加载一个学生,计数器加1
(*count)++;
}

fclose(file);
printf("已从文件 %s 加载 %d 条学生信息\n", FILE_PATH, *count);
}


int main() {
struct Student students[500];
int count = 0;
int choice;
int init = 0;
int clearscreen = 1;

// 加载已有的学生信息
loadStudentsFromFile(students, &count);
printf("成功加载 %d 名学生\n", count);
for (int i = 0; i < count; i++) {
printf("加载的学生:姓名:%s 学号:%lld 成绩:%.2f\n", students[i].name, students[i].id, students[i].score);
}

while(1){
// 调用清屏函数
if (init > 0) {
int validInput = 0;
while (!validInput) {
printf("输入 0 或 1 选择是否清屏:\n");
printf("1. 清屏\n");
printf("0. 不清屏\n");
printf("输入值为:");


//为了防止输入出0和1以外的其他数字影响程序
//所以要判断输入的是0还是1(在开始写这个代码时就遇到这个问题了)
// 即在输入的数字scanf("%d", &clearscreen) == 1 为整数合法的情况下
//的同时满足 clearscreen为0或者1的条件
if (scanf("%d", &clearscreen) == 1 && (clearscreen == 0 || clearscreen == 1)) {
//满足条件后将validInput的值改为1 ,!validInput就为0,退出while循环
validInput = 1;
if (clearscreen == 1) {
clearScreen(); // 调用清屏函数
}
} else {
//如果输入的不是0或1
printf("无效的输入,您只能输入0或者1哦\n");
while (getchar() != '\n'); // 清空输入缓冲区
}
}
}
init = 1;
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(" 8. 显示所有信息\n");
printf(" 0. 退出系统\n");
printf(" 请选择操作:只能输入0-8中的一个\n");
printf("\n输入值为:");
scanf("%d", &choice); // 输入操作选项
printf("\n");
switch (choice) {
case 1:
printf("输入学生信息\n");
inputStudent(students, &count);
printf("\n");
saveStudentsToFile(students, count);
break;
case 2:
printf("查找学生信息\n");
searchStudent(students, count);
printf("\n");
break;
case 3:
printf("删除学生信息\n");
deleteStudent(students, &count);
printf("\n");
saveStudentsToFile(students, count);
break;
case 4:
printf("修改学生信息\n");
modifyStudent(students, count);
printf("\n");
saveStudentsToFile(students, count);
break;
case 5:
printf("插入学生信息\n");
insertStudent(students, &count);
printf("\n");
saveStudentsToFile(students, count);
break;
case 6:
printf("根据成绩排名\n");
rankStudents(students, count);
printf("\n");
break;
case 7:
printf("统计学生总数\n");
countStudents(count);
printf("\n");
break;
case 8:
printf("显示所有信息\n");
printAllStudents(students, count); // 调用函数显示所有学生信息
printf("\n");
break;
case 0:
{
if (confirmExit()) {
// 调用确认函数
printf("\n");
printf("退出系统!!! 感谢您的使用 Ciallo~(∠.ω< )⌒★\n");
// 如果确认退出,则退出程序
exit(0);
}
saveStudentsToFile(students, count);
break;
}

default:
printf("无效的选项,您只能输入0~8中的一个哦。\n");
printf("\n");
}
}
return 0;
}