服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - C/C++ - C语言实现简单学生选课管理系统

C语言实现简单学生选课管理系统

2021-07-22 16:45AlbeltBO C/C++

这篇文章主要为大家详细介绍了C语言实现简单学生选课管理系统,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

本文实例为大家分享了C语言实现学生选课管理系统的具体代码,供大家参考,具体内容如下

这是我们大一C语言课程设计的最终作品,涉及文件读写操作、链表的一系列操作。

源代码由头文件all.h、主函数文件main.cpp以及功能函数文件student.cpp、manager.cpp、common.cpp组成。

涉及的文件读写操作需要先手动创建文件,文件路径可以在all.h的宏定义中更改

使用vs2017的c++编译器,兼容c语言,现贴上源代码和运行截图,供感兴趣的童鞋参考,水平有限还望多多包涵。

运行截图

C语言实现简单学生选课管理系统

all.h

?
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
#pragma once
#define MAXN 50
#define STU_F  "C:\\stu_cour_info_system\\date\\student.txt"  //文件存放路径及文件名
#define COUR_F  "C:\\stu_cour_info_system\\date\\course.txt"  //文件存放路径及文件名
#define MAN_F  "C:\\stu_cour_info_system\\date\\manager.txt"     //文件存放路径及文件名
 
#define STU_F_BACKUP  "C:\\stu_cour_info_system\\backup\\student.txt"  //备份文件存放路径及文件名
#define COUR_F_BACKUP  "C:\\stu_cour_info_system\\backup\\course.txt"   //备份文件存放路径及文件名
#define MAN_F_BACKUP  "C:\\stu_cour_info_system\\backup\\manager.txt"      //备份文件存放路径及文件名
 
struct student //学生信息结构体
{
 char name[MAXN];      //姓名
 char num[MAXN];  //学号
 char sch_cla[20];       //学院和班级
 double score_all = 0; //应选总学分
 double score_sel = 0; //已选课总学分
 char password[9];  //学生登陆密码,共8位
 int course_sum;  //选课总数
 char course[50][MAXN];  //记录选课课程的编号
 struct student *next;  //链表指针
};
 
struct course //课程信息结构体
{
 char num[MAXN];  //课程编号
 char name[MAXN];  //课程名称
 char nature[MAXN];  //课程性质
 char term[MAXN];  //开课学期
 double time_all;    //总学时
 double time_teach;   //授课学时
 double time_exp;   //实验或上机学时
 double score;    //该课程学分
 int stu_max;   //能够容纳的学生总数
 int stu_sum;   //已经选课学生总数
 char stu[100][MAXN];  //已经选课学生学号
 struct course *next;  //链表指针
};
 
/*通用函数*/
int judge_num(char *ch);         //用于检测输入的字符串ch是否全部为数字,全部为数字则返回1,否则返回0
int input_num();          //用于输入数字,如果输入的全部为数字则返回该数字,否则一直停在输入状态
double input_double();                                   //用于输入小数
int input_limit(int n);         //输入选项,控制输入的数字范围为0-n,在这个范围内则返回该数字,否则一直停在输入状态
int input_limit0(int n);
int keyexam(char *actual_key, char *input_key);   //密码检测函数,x为密码位数,actul_key[]为真实密码,input_key为输入密码,密码匹配返回1否则返回0
student* load_stu();          //将学生文件生成链表,返回链表头指针
void store_stu(student *p_head);       //将学生链表存入学生文件,需传入链表头指针
course* load_cour();          //将课程文件生成链表,返回链表头指针
void store_cour(course *p_head);       //将课程链表存入课程文件,需传入链表头指针
student* locate_end(student *head);                         //传入头节点,返回尾节点
course* locate_end(course *head);                          //传入头节点,返回尾节点
void help();            //显示帮助信息
int link_count(student* head);
int link_count(course* head);        //计算链表节点数量
int judge_ascii_num(char in[]);                             //检测输入是否全部为ASCII的数字,是返回1否则返回0
 
 
           /*管理员函数*/
int man_login();          //管理员登陆函数,密码正确返回1,否则返回0
int man_menu();           //管理员主菜单,返回对应的输入值
void student_add(student *head);        //增加学生的函数
void student_delete(student *head);        //删除学生的函数
void man_search_stu(student *head);        //搜索学生的函数
void student_modify(student *head);       //管理员修改学生信息
void course_add(course *head);        //增加课程的函数
void course_delete(course *head);       //删除课程的函数
void course_modify(course *head);       //修改课程信息的函数
void print_all();                                     //打印所有学生和课程的函数
void man_modifyKey();         //管理员修改密码
void man_backups_recover();        //管理员备份和恢复数据
void courseshowone_man(course *ad);     //管理员显示一门课程信息
void courseshowall_man(course *ad);      //管理员显示所有课程信息
 
          /*学生函数*/
student* stu_login(student* head);       //学生登陆函数,学号和密码都正确则返回链表中该学生的指针,错误则返回null
int stu_menu();          //学生菜单,返回对应的输入值
void student_showone(student *p);       //显示一个学生的信息
void student_showall(student *head);      //显示所有学生的信息
student *studentnamefind_char(student *head, char tar[]);   //根据学生姓名查找学生,如果学生为头节点则返回空指针,不为头节点则返回前一个节点的指针,不存在则返回尾节点
student *studentnamefind_num(student *head, char tar[]);   //根据学生学号查找学生,如果学生为头节点则返回空指针,不为头节点则返回前一个节点的指针,不存在则返回尾节点
void stu_modifyKey(student* stu);       //学生修改密码
void coursechoose(course* head, student* stu);   //选课函数,min为最少要达到的学分
void courseshow_nature(course *head);      //根据课程性质查找并显示课程信息
void courseshow_term(course *head);      //根据开课学期查找并显示课程信息
void cour_nat_te(course* head);                          //根据课程性质与开课学期组合查找课程信息
void coursenumfindtip(course *head);      //查课子函数
void coursenamefindtip(course *head);      //查课子函数2
void stu_dele_cour(course* head, student* stu);    //删除已选课程
 
          /*课程函数*/
void course_showone(course *ad);       //显示一门的信息
void course_showall(course *head);       //显示所有课程的信息
void search_course(course *head);        //搜索课程的函数
course *coursenamefind_char(course* head, char tar[]);    //根据课程名称查找课程节点,如果课程为头节点则返回空指针,不为头节点则返回前一个节点的指针,不存在则返回尾节点
course *coursenumfind_num(course* head, char tar[]);    //根据课程编号查找课程,如果课程为头节点则返回空指针,不为头节点则返回前一个节点的指针,不存在则返回尾节点

main.cpp

?
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
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include"all.h"
 
student* stu_head;
course* cour_head;
course *cour_tail;
student *stu_tail;     //这四个指针是全局变量
 
int main()
{
 /*对四个指针变量初始化*/
 stu_head = load_stu();    //stu_head指向学生链表头
 stu_tail = locate_end(stu_head);  //stu_tail指向学生链表尾
 cour_head = load_cour();   //cour_head指向课程链表头
 cour_tail = locate_end(cour_head); //cour_tail指向课程链表尾
 
 //{/*这段代码用于生成原始管理员密码:10个0;
 // 编译链接后执行一次然后注释掉*/
 // FILE *fp = fopen(MAN_F, "w+");
 // for (int i = 0; i < 10; i++)
 // {
 // fputc('0', fp);
 // }
 // fclose(fp);
 //}
 
 
 printf("\n\t\t--------------------------------欢迎使用选课系统!---------------------------------\n");
 int status=-1;
 while (1)//判断登陆类型
 {
 status = -1;
 printf("\n\n\t\t*****请选择登陆类型 [1]学生  [2]管理员  [3]显示帮助  [0]退出系统:");
 status = input_limit0(3);
 if ((status == 0) || (status == 1) || (status == 2)||(status==3))
  break;
 else
  printf("\n\t\t##### 输入错误!只能选择1、2或0 #######\n");
 }
 
 while (1)
 {
 if (status == 2)//管理员登陆
 {
  if (man_login() == 1)
  {
  printf("\n\n\t\t-----------------------------------管理员登陆成功!--------------------------------\n\n");
  int menu_return = man_menu();
  while (1)
  {
   switch (menu_return)
   {
   case 1:
   student_add(stu_head); break;
   case 2:
   student_delete(stu_head); break;
   case 3:
   student_modify(stu_head); break;
   case 4:
   man_search_stu(stu_head); break;
   case 5:
   course_add(cour_head); break;
   case 6:
   course_delete(cour_head); break;
   case 7:
   course_modify(cour_head); break;
   case 8:
   search_course(cour_head); break;
   case 9:
   print_all(); break;
   case 10:
   man_modifyKey(); break;
   case 11:
   man_backups_recover(); break;
   case 0:
   break;
   default:
   printf("\t\t\t#####输入错误,请重新输入######!\n");
   }
 
   if (menu_return == 0)
   break;
   menu_return = man_menu();
  }
  }
  else
  printf("\t\t######密码错误,请重新登陆!######\n");
 }
 
 else if (status == 1)//student login
 {
  student* p_stu = stu_login(stu_head);
  if (p_stu != NULL)//p_stu为指向该学生的指针
  {
  printf("\t\t*******请输入登陆密码:");
  char input[100];
  scanf("%s", input);
  while (getchar() != '\n');
  if (strcmp(p_stu->password, input) == 0)
  {
   printf("\n\n\t\t-----------------------------%s 欢迎进入选课系统! ---------------------------------\n\n", p_stu->name);
   int menu_return = stu_menu();
   while (1)
   {
   switch (menu_return)
   {
   case 1:
    course_showall(cour_head); break;
   case 2:
    search_course(cour_head); break;
   case 3:
    coursechoose(cour_head,p_stu); break;
   case 4:
    stu_dele_cour(cour_head, p_stu); break;
   case 5:
    student_showone(p_stu); break;
   case 6:
    stu_modifyKey(p_stu); break;
   case 0:
    break;
   default:
    printf("\t\t######输入错误,请重新输入!######\n");
   }
 
   if (menu_return == 0)
    break;
   menu_return = stu_menu();
   }
  }
  else
  {
   printf("\t\t#####密码错误,请重新登陆!#######\n");
  }
  }
  else
  printf("\t\t#####该学号不存在,请重新登陆!######\n");
  p_stu = NULL;
 }
 
 else if (status == 3)//显示帮助信息
  help();
 
 else if (status == 0)//关闭系统
  return 0;
 
  while (1)//再次判断登陆类型
  {
  status = -1;
  printf("\n\n\t\t*****请选择登陆类型 [1]学生  [2]管理员  [3]显示帮助  [0]退出系统:");
  status = input_limit0(3);
  if ((status == 0) || (status == 1) || (status == 2) || (status == 3))
   break;
  else
   printf("\n\t\t##### 输入错误!只能选择1、2或0 #######\n");
  }
 }
}

common.cpp

?
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
#include<stdio.h>
#include<string.h>
#include"all.h"
#include<stdlib.h>
#include<malloc.h>
#include<ctype.h>
 
extern student* stu_head;
extern course* cour_head;
extern course *cour_tail;
extern student *stu_tail;  // 这四个指针变量在main.cpp中已经声明为全局变量
 
int keyexam(char *actual_key, char *input_key)//密码正确则返回1,否则返回0
{
 if (strcmp(actual_key, input_key) == 0)
 return 1;
 else
 return 0;
}
 
student* load_stu()//经调试已经正确
{
 int count = 0;
 FILE *fp;
 if ((fp = fopen(STU_F, "r")) == NULL)
 {
 printf("\t\tcannot open the file:STU_F\n");
 exit(0);
 }
 student* temp = (student*)malloc(sizeof(student));
 while (!feof(fp))
 {
 if (fread(temp, sizeof(student), 1, fp))
  count++;
 }
 free(temp);
 temp = NULL;
 
 if (count == 0)
 return NULL;
 else
 {
 rewind(fp);
 student *p_head = NULL;//文件中有链表信息,则创建一个头指针
 p_head = (student*)malloc(sizeof(student));
 fread(p_head, sizeof(student), 1, fp);//用文件内容初始化链表节点
 p_head->next = NULL;
 count--;
 student* p_new = p_head;
 student* p_end = p_head;
 for (int i = 0; i < count; i++)
 {
  p_new = (student*)malloc(sizeof(student));
  fread(p_new, sizeof(student), 1, fp);
  p_new->next = NULL;
  p_end->next = p_new;
  p_end = p_new;
 }
 fclose(fp);
 return p_head;
 }
}
 
void store_stu(student * p_head)//经调试已正确
{
 FILE *fp;
 if ((fp = fopen(STU_F, "w")) == NULL)//以只写方式打开文件,覆盖以前数据
 {
 printf("\t***STU_F missed,please quit the system and check for that!\n\n");
 exit(0);
 }
 while (p_head != NULL)//将链表所有节点写入缓冲区
 {
 fwrite(p_head, sizeof(student), 1, fp);//将链表一个节点写入缓冲区
 p_head = p_head->next;      //p_head指向下一个节点
 }
 fclose(fp);//保存文件,清空缓冲区
}
 
course * load_cour()
{
 int count = 0;
 FILE *fp;
 if ((fp = fopen(COUR_F, "r")) == NULL)
 {
 printf("\t\tcannot open the file:COUR_F\n");
 exit(0);
 }
 course* temp = (course*)malloc(sizeof(course));
 while (!feof(fp))
 {
 if (fread(temp, sizeof(course), 1, fp))
  count++;
 }
 free(temp);
 temp = NULL;
 
 if (count == 0)
 return NULL;
 else
 {
 rewind(fp);
 course *p_head = NULL;//文件中有链表信息,则创建一个头指针
 p_head = (course*)malloc(sizeof(course));
 fread(p_head, sizeof(course), 1, fp);//用文件内容初始化链表节点
 p_head->next = NULL;
 count--;
 course* p_new = p_head;
 course* p_end = p_head;
 for (int i = 0; i < count; i++)
 {
  p_new = (course*)malloc(sizeof(course));
  fread(p_new, sizeof(course), 1, fp);
  p_new->next = NULL;
  p_end->next = p_new;
  p_end = p_new;
 }
 fclose(fp);
 return p_head;
 }
 
}
 
void store_cour(course * p_head)
{
 FILE *fp;
 if ((fp = fopen(COUR_F, "w")) == NULL)//以只写方式打开文件,覆盖以前数据
 {
 printf("\t***COUR_F missed,please quit the system and check for that!\n\n");
 exit(0);
 }
 while (p_head != NULL)//将链表所有节点写入缓冲区
 {
 fwrite(p_head, sizeof(course), 1, fp);//将链表一个节点写入缓冲区
 p_head = p_head->next;      //p_head指向下一个节点
 }
 fclose(fp);//保存文件,清空缓冲区
}
 
student * locate_end(student * head)
{
 student* end = head;
 while (head != NULL)
 {
 end = head;
 head = head->next;
 }
 return end;
}
 
course* locate_end(course * head)
{
 course* end = head;
 while (head != NULL)
 {
 end = head;
 head = head->next;
 }
 return end;
}
 
void help()
{
 int input = -1;
 while (1)
 {
 printf("\n\t\t*****请选择需要的帮助类型 [1]学生帮助 [2]管理员帮助 [3]版权信息 [0]返回主页:");
 scanf("%d", &input);
 while (getchar() != '\n');
 if (input == 0)
  break;
 else if (input == 1)//学生使用说明
 {
  printf("\n\t\t--------------------------------学生使用说明---------------------------------------\n");
  printf("\t\t密码:初始密码为学号,忘记密码请联系管理员\n");
  printf("\t\t\n");
  printf("\t\t\n");
  printf("\t\t\n");
  printf("\t\t-----------------------------------------------------------------------------------\n\n");
 }
 else if (input == 2)//管理员使用说明
 {
  printf("\n\t\t-------------------------------管理员使用说明---------------------------------------\n");
  printf("\t\t密码:初始密码为10个0,首次使用务必修改密码!\n");
  printf("\t\t警告:该软件的文件夹必须放在C盘根目录下,否则不能使用!\n");
  printf("\t\t提示:请定时备份数据,防止数据丢失!\n");
  printf("\t\t提示:学生学号和课程编号只能是数字!\n");
  printf("\t\t------------------------------------------------------------------------------------\n\n");
 }
 else if (input == 3)//版权信息
 {
  printf("\n\t\t------------------------------版权信息-------------------------------------------------\n");
  printf("\t\t软件名称:学生及课程信息管理系统\n");
  printf("\t\t开发人员:焦智洋、文诗波、韩旭\n");
  printf("\t\t版本:beta1.0\n");
  printf("\t\t版权保护:版权所有,翻版必究\n");
  printf("\t\t---------------------------------------------------------------------------------------\n\n");
 }
 else
  printf("\n\t\t#####输入错误,请重新输入!#####\n");
 }
}
 
int link_count(student * head)
{
 int count = 0;
 while (head != NULL)
 {
 count++;
 head = head->next;
 }
 return count;
}
 
int link_count(course * head)
{
 int count = 0;
 while (head != NULL)
 {
 count++;
 head = head->next;
 }
 return count;
}
 
int judge_ascii_num(char in[])
{
 int i = 0;
 while (in[i]!='\0')
 {
 if ((in[i] < '0') || (in[i] > '9'))
  return 0;
 i++;
 }
 return 1;
}
 
int judge_num(char *ch)
{
 int sum = 0, len = strlen(ch);
 for (int i = 0; i < len; i++)
 {
 if (ch[i] >= '0'&&ch[i] <= '9')
  sum++;
 }
 if (sum == len)
 return 1;
 else
 return 0;
}
 
int input_num()
{
 int num;
 char buf[MAXN];
 while ((scanf("%s", buf) == 0) || (judge_num(buf) == 0))
 {
 while (getchar() != '\n');
 printf("\n\t\t###输入错误,请重新输入:");
 }
 num = atoi(buf);
 return num;
}
 
double input_double()
{
 double temp = -1.00;
 while (1)
 {
 scanf("%lf", &temp);
 while (getchar() != '\n');
 if (temp < 0)
  printf("\n\t\t#####输入错误,请重新输入:");
 else
  break;
 }
 return temp;
}
 
double judge_input_dou()
{
 printf("\n\t\t是否修改该项?[1]修改  [0]不修改:");
 int judge = 0;
 scanf("%d", &judge);
 while (getchar() != '\n');
 if (judge == 1)
 {
 while (1)
 {
  printf("\n\t\t请输入修改后的内容:");
  double in = 0.00;
  scanf("%lf", &in);
  while (getchar() != '\n');
  if (in<=0)
  printf("\n\t\t#####输入错误,请重新输入!######");
  else
  {
  return in;
  break;
  }
 }
 }
 else
 return -1.0;
}
 
course *coursenamefind_char(course* head, char tar[])//根据课程名称查找课程节点,返回前一节点地址
{
 course *p, *q;
 p = head;
 q = NULL;
 while (p != NULL)
 {
 if (strcmp(tar, p->name) == 0)
  return q;
 q = p;
 p = p->next;
 }
 return q;
}
 
course *coursenumfind_num(course* head, char tar[])//根据课程编号查找课程
{course *p, *q;
 p = head;
 q = NULL;
 while (p != NULL)
 {
 if (strcmp(tar, p->num)==0)
  return q;
 q = p;
 p = p->next;
 }
 return q;
 
}
 
student *studentnamefind_char(student *head, char tar[])
{
 student *p, *q;
 p = head;
 q = NULL;
 while (p != NULL)
 {
 if (strcmp(tar, p->name) == 0)
  return q;
 q = p;
 p = p->next;
 }
 return q;
}
 
student* studentnamefind_num(student *head, char tar[])
{
 student *p, *q;
 p = head;
 q = NULL;
 while (p != NULL)
 {
 if (strcmp(tar, p->num) == 0)
  return q;
 q = p;
 p = p->next;
 }
 return q;
}
 
int input_limit(int n)
{
 int m;
 while (1)
 {
 m = input_num();
 if (m > 0 && m <= n)
  break;
 printf("\n\t\t####无此选项,请重新输入!####\n");
 }
 return m;
}
 
int input_limit0(int n)
{
 int m;
 while (1)
 {
  m = input_num();
  if (m >= 0 && m <= n)
  break;
  printf("\n\t\t####无此选项,请重新输入!####\n");
 }
 return m;
}
 
void student_showone(student *p)
{
 printf("\n\t\t------------------------------------------------------");
 printf("\n\t\t学号:%s", p->num);
 printf("\n\t\t姓名:%s", p->name);
 printf("\n\t\t学院与班级:%s", p->sch_cla);
 printf("\n\t\t密码:%s", p->password);
 if (p->course_sum == 0)
 printf("\n\t\t该学生无已选课程!\n");
 else
 {
 printf("\n\t\t已选课程:\n");
 for (int i = 0; i < p->course_sum; i++)
  printf("\t\t\t[%d]:%s\n", i + 1, p->course[i]);
 }
 printf("\t\t选课总数:%d", p->course_sum);
 printf("\n\t\t已选课程总学分:%lf", p->score_sel);
 printf("\n\t\t已得学分统计:%lf", p->score_all);
 printf("\n\t\t------------------------------------------------------");
}
 
void student_showall(student *head)
{
 student *p;
 p = head;
 while (p != NULL)
 {
 student_showone(p);
 p = p->next;
 }
}
 
void course_showone(course *ad)
{
 if (ad == NULL)
 printf("\t\t无课程\n");
 else
 {
 printf("\n\t\t------------------------------------------------------");
 printf("\n\t\t课程名称:%s\n", ad->name);
 printf("\n\t\t课程编号:%s\n", ad->num);
 printf("\t\t课程性质:%s\n", ad->nature);
 printf("\t\t开课学期:%s\n", ad->term);
 printf("\t\t总学时:%lf\n", ad->time_all);
 printf("\t\t授课学时:%lf\n", ad->time_teach);
 printf("\t\t实验或上机学时:%lf\n", ad->time_exp);
 printf("\t\t学分:%lf\n\n", ad->score);
 printf("\n\t\t------------------------------------------------------");
 }
}
 
void course_showall(course *head)
{
 course *p;
 p = head;
 while (p != NULL)
 {
 course_showone(p);
 p = p->next;
 }
 return;
}
 
void cour_nat_te(course* head)
{
 while (1)
 {
 printf("\n\t\t请输入要查找课程的性质,返回上级菜单请输入0000:");
 char input1[50];
 scanf("%s", input1);
 while (getchar() != '\n');
 if (strcmp(input1, "0000") == 0)
  break;
 
 printf("\n\t\t请输入要查找课程的开课学期:");
 char input2[50];
 scanf("%s", input2);
 while (getchar() != '\n');
 
 int count = 0;
 while (head != NULL)
 {
  if ((strcmp(input1, head->nature) == 0) && (strcmp(input2, head->term) == 0))
  {
  course_showone(head);
  count++;
  }
  head = head->next;
 }
 if (count == 0)
  printf("\n\t\t#####没有符合查找条件的课程!#####\n");
 }
}
 
void search_course(course *head)
{
 int flag;
 while (true)
 {
 flag = 0;
 printf("\n\t\t请输入查找条件 [1]课程编号  [2]课程名称  [3]课程性质\n\t\t[4]开课学期  [5]课程性质与开课学期  [0]返回上级菜单:");
 scanf("%d", &flag);
 while (getchar() != '\n');
 switch (flag)
 {
 case(1):coursenumfindtip(head); break;
 case(2):coursenamefindtip(head); break;
 case(3):courseshow_nature(head); break;
 case(4):courseshow_term(head); break;
 case(5):cour_nat_te(head); break;
 case(0):break;
 default:
  printf("\n\t\t#####输入错误,请重新输入!#####");
 }
 if (flag == 0)
  break;
 }
}

manager.cpp

?
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
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
#include<stdio.h>
#include<string.h>
#include"all.h"
#include<stdlib.h>
#include<malloc.h>
#include<ctype.h>
 
extern student* stu_head;
extern course* cour_head;
extern course *cour_tail;
extern student *stu_tail;  // 这四个指针变量在main.cpp中已经声明为全局变量
 
int man_login()
{
 FILE *fp;
 if ((fp = fopen(MAN_F, "r")) == NULL)
 {
 printf("\t\t#######无法找到文件:MAN_F######\n");
 return -1;
 }
 char key[11];
 fread(key, 10, 1, fp);
 key[10] = '\0';
 fclose(fp);
 char input[1000];
 printf("\t\t*******请输入管理员密码:");
 scanf("%s", input);
 while (getchar() != '\n');
 if (strcmp(input, key) == 0)
 return 1;
 else
 return 0;
}
 
int man_menu()
{
 printf("\n\t\t~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~管理员菜单~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
 printf("\n\t\t---[1]:添加学生");
 printf("\n\t\t---[2]:删除学生");
 printf("\n\t\t---[3]:修改学生信息");
 printf("\n\t\t---[4]:查找学生信息\n");
 printf("\n\t\t---[5]:添加课程");
 printf("\n\t\t---[6]:删除课程");
 printf("\n\t\t---[7]:修改课程信息");
 printf("\n\t\t---[8]:查找课程信息\n");
 printf("\n\t\t---[9]:打印所有课程/学生信息");
 printf("\n\t\t---[10]:修改管理员密码");
 printf("\n\t\t---[11]:数据备份与恢复");
 printf("\n\t\t---[0]:注销\n");
 printf("\n\t\t----请从<0-10>中选择操作类型:");
 int n = input_limit0(11);
 return n;
}
 
void student_add(student *head) //增加学生的函数
{
 while (1)
 {
 char input[50];
 while (1)
 {
  printf("\n\t\t请输入要添加学生的学号(数字),返回上级菜单请输入0000:");
  scanf("%s", input);
  while (getchar() != '\n');
  if (judge_ascii_num(input) == 1)
  break;
  else
  printf("\n\t\t####输入错误!#####");
 }
 if (strcmp(input, "0000") == 0)
  break;
 if (studentnamefind_num(stu_head, input) != stu_tail)
 {
  printf("\t\t###已存在该学生,请重新输入!####\n");
  continue;
 }
 
 /*初始化学生信息*/
 student* p = (student *)malloc(sizeof(student));
 strcpy(p->num, input);
 printf("\t\t请输入学生姓名:");
 scanf("%s", p->name);
 while (getchar() != '\n');
 printf("\t\t请输入学生学院和班级(用--隔开):");
 scanf("%s", p->sch_cla);
 while (getchar() != '\n');
 printf("\t\t请输入当前该学生总学分:");
 p->score_all = input_double();
 p->course_sum = 0;
 p->score_sel = 0.0;
 strcpy(p->password, p->num);
 
 if (stu_head == NULL)//当前链表中没有节点
 {
  p->next = NULL;
  stu_head = p;
  stu_tail = p;
 }
 else
 {
  if (strcmp(p->num, stu_head->num) < 0)//新增节点的标号比头节点还小
  {
  p->next = stu_head;
  stu_head = p;
  }
  else if (strcmp(p->num, stu_tail->num) > 0)//新增节点的标号比尾节点还大
  {
  p->next = NULL;
  stu_tail->next = p;
  stu_tail = p;
  }
  else//新增节点的标号在头节点和尾节点之间
  {
  student* temp = stu_head;
  while (temp != stu_tail)
  {
   if (strcmp(p->num, temp->num) > 0)
   {
   p->next = temp->next;
   temp->next = p;
   break;
   }
  }
  }
 }
 printf("\n\t\t学生信息录入成功!\n");
 }
 
 store_stu(stu_head);
}
 
void student_delete(student *head)
{
 while (true)
 {
 printf("\n\t\t请输入要删除学生的学号或姓名,取消删除请输入0000:");
 char input[50];
 scanf("%s", input);
 while (getchar() != '\n');
 if (strcmp(input, "0000") == 0)
  break;
 
 student *p;
 if ((input[0] >= 48) && (input[0] <= 57))
  p = studentnamefind_num(stu_head, input);
 else
  p = studentnamefind_char(stu_head, input);
 
 if (p == stu_tail)//没有该学生
 {
  printf("\n\t\t####没有该学生信息!#####");
  continue;
 }
 
 printf("\n\t\t确定删除%s?[1]是 [0]否:", input);
 int in = 0;
 scanf("%d", &in);
 while (getchar() != '\n');
 if (in == 1)
 {
  if (p == NULL)//链表头节点
  {
  if (stu_head->next == NULL)
  {
   stu_tail = NULL;
  }
  student* temp = stu_head;
  stu_head = stu_head->next;
  free(temp);
  temp = NULL;
  }
  else if (p->next == stu_tail)//链表尾节点
  {
  p->next = NULL;
  free(stu_tail);
  stu_tail = p;
  }
  else//链表中间节点
  {
  student* delete_point = p->next;
  p->next = delete_point->next;
  free(delete_point);
  delete_point = NULL;
  }
  printf("\n\t\t已经删除该学生的信息!\n");
 }
 else
  printf("\n\t\t####未删除该学生的信息!####\n");
 }
 
 store_stu(stu_head);
}
 
void student_modify(student *head)
{
 char input[100];
 student* find = NULL;
 while (1)
 {
 printf("\t\t请输入要修改学生的学号或姓名,取消修改请输入0000:");
 scanf("%s", input);
 while (getchar() != '\n');
 if (strcmp(input, "0000") == 0)
  break;
 if ((input[0] >= 48) && (input[0] <= 57))//按学号查找
  find = studentnamefind_num(head, input);
 else//按姓名查找
  find = studentnamefind_char(head, input);
 if (find == stu_tail)
 {
  printf("\n\t\t####你所查找的学生不存在!");
  continue;
 }
 else
 {
  char temp[50];
  if (find == NULL)
  find = head;
  else
  find = find->next;
  printf("\n\t\t请分别输入需要修改的内容,若某一项不需要修改请输入0");
 
  printf("\n\t\t原姓名:%s  修改后的姓名:", find->name);
  scanf("%s", &temp);
  while (getchar() != '\n');
  if (strcmp(temp, "0") != 0)
  strcpy(find->name, temp);
 
  printf("\t\t原学院和班级:%s  修改后的学院和班级(中间用--隔开):", find->sch_cla);
  scanf("%s", &temp);
  while (getchar() != '\n');
  if (strcmp(temp, "0") != 0)
  strcpy(find->sch_cla, temp);
 
  printf("\t\t原密码:%s  修改后的密码:", find->password);
  scanf("%s", &temp);
  while (getchar() != '\n');
  if (strcmp(temp, "0") != 0)
  strcpy(find->password, temp);
 
  printf("\t\t原总学分:%lf  (增加学分请使用+,减少学分请使用-,例如“-10” “+10”):", find->score_all);
  scanf("%s", &temp);
  while (getchar() != '\n');
  if (strcmp(temp, "0") != 0)
  {
  int change = (int)temp[0];
  temp[0] = '0';
  double number = atof(temp);
  if (change == 43)
   find->score_all += number;
  else if (change == 45)
   find->score_all -= number;
  }
 
  printf("\t\t修改完成!\n\n");
 }
 }
 
 store_stu(stu_head);
}
 
void course_add(course *head)
{
 while (1)
 {
 char input[50];
 while (1)
 {
  printf("\n\t\t请输入要添加课程的编号,返回上一级菜单请输入0000:");
  scanf("%s", input);
  while (getchar() != '\n');
  if (judge_ascii_num(input) == 1)
  break;
  else
  printf("\n\t\t#####输入错误!####");
 }
 if (strcmp(input, "0000") == 0)
  break;
 
 if (coursenumfind_num(cour_head, input) != cour_tail)
 {
  printf("\t\t###已存在该课程,请重新输入!####\n");
  continue;
 }
 
 course* p = (course*)malloc(sizeof(course));
 /*初始化课程信息*/
 strcpy(p->num, input);
 printf("\n\t\t请输入课程名称:");
 scanf("%s", p->name);
 while (getchar() != '\n');
 printf("\n\t\t请输入课程性质:");
 scanf("%s", p->nature);
 while (getchar() != '\n');
 printf("\n\t\t请输入课程总学时:");
 p->time_all = input_double();
 printf("\n\t\t请输入课程授课学时:");
 p->time_teach = input_double();
 printf("\n\t\t请输入课程实验或上机学时:");
 p->time_exp = input_double();
 printf("\n\t\t请输入课程最大容纳人数:");
 p->stu_max = input_num();
 printf("\n\t\t请输入课程学分:");
 p->score = input_double();
 printf("\n\t\t请输入课程开课学期:");
 scanf("%s", p->term);
 while (getchar() != '\n');
 p->stu_sum = 0;
 
 if (cour_head == NULL)//链表中没有节点
 {
  p->next = NULL;
  cour_head = p;
  cour_tail = p;
 }
 else
 {
  if (strcmp(p->num, cour_head->num) < 0)//新增节点的标号比头节点还小
  {
  p->next = cour_head;
  cour_head = p;
  }
  else if (strcmp(p->num, cour_tail->num) > 0)//新增节点的标号比尾节点还大
  {
  p->next = NULL;
  cour_tail->next = p;
  cour_tail = p;
  }
  else//新增节点的标号在头节点和尾节点之间
  {
  course* temp = cour_head;
  while (temp != cour_tail)
  {
   if (strcmp(p->num, temp->num) > 0)
   {
   p->next = temp->next;
   temp->next = p;
   break;
   }
  }
  }
 }
 printf("\n\t\t课程信息录入成功!\n");
 }
 store_cour(cour_head);
}
 
void course_delete(course *head)
{
 course *p;
 char input[50];
 while (true)
 {
 printf("\n\t\t请输入要删除课程的编号或名称,取消删除请输入0000:");
 scanf("%s", input);
 while (getchar() != '\n');
 if (strcmp(input, "0000") == 0)
  break;
 if ((input[0] >= 48) && (input[0] <= 57))
  p = coursenumfind_num(head, input);
 else
  p = coursenamefind_char(head, input);
 
 if (p == cour_tail)//没有该课程
 {
  printf("\n\t\t####没有该课程信息!####"); continue;
 }
 
 printf("\n\t\t确定删除%s?[1]是 [0]否:", input);
 int in = 0;
 scanf("%d", &in);
 while (getchar() != '\n');
 if (in == 1)
 {
  if (p == NULL)//链表头节点
  {
  if (head->next == NULL)
   cour_tail = NULL;
  course* temp = head;
  head = head->next;
  cour_head = head;
  free(temp);
  }
  else if (p->next == cour_tail)//链表尾节点
  {
  free(cour_tail);
  p->next = NULL;
  cour_tail = p;
  }
  else//链表中间节点
  {
  course* delete_point = p->next;
  p = (p->next)->next;
  free(delete_point);
  }
  printf("\n\t\t%s已经删除!\n", input);
 }
 else
  printf("\n\t\t#####未删除课程%s的信息!######\n", input);
 }
 store_cour(cour_head);
}
 
void course_modify(course *head)
{
 char input[100];
 course* find = NULL;
 while (1)
 {
 printf("\t\t请输入要修改课程的编号号或名称,取消修改请输入0000:");
 scanf("%s", input);
 while (getchar() != '\n');
 if (strcmp(input, "0000") == 0)
  break;
 if ((input[0] >= 48) && (input[0] <= 57))//按学号查找
  find = coursenumfind_num(head, input);
 else//按姓名查找
  find = coursenamefind_char(head, input);
 if (find == cour_tail)
 {
  printf("\n\t\t####你所查找的课程不存在!####");
  continue;
 }
 else
 {
  char temp[50];
  if (find == NULL)
  find = head;
  else
  find = find->next;
  printf("\n\t\t请分别输入需要修改的内容,若某一项不需要修改请输入0");
 
  printf("\n\t\t原名称:%s     修改后的名称:", find->name);
  scanf("%s", &temp);
  while (getchar() != '\n');
  if (strcmp(temp, "0") != 0)
  strcpy(find->name, temp);
 
  printf("\t\t原性质:%s     修改后的性质:", find->nature);
  scanf("%s", &temp);
  while (getchar() != '\n');
  if (strcmp(temp, "0") != 0)
  strcpy(find->nature, temp);
 
  printf("\t\t原开课学期:%s     修改后的开课学期:", find->term);
  scanf("%s", &temp);
  while (getchar() != '\n');
  if (strcmp(temp, "0") != 0)
  strcpy(find->term, temp);
 
  //int time_all;    //总学时
  //int time_teach;   //授课学时
  //int time_exp;   //实验或上机学时
  //int score;    //该课程学分
  //int stu_max;   //能够容纳的学生总数
 
  printf("\t\t原总学时:%lf     修改后的总学时:", find->time_all);
  scanf("%s", &temp);
  while (getchar() != '\n');
  if (strcmp(temp, "0") != 0)
  find->time_all = atof(temp);
 
  printf("\t\t原授课学时:%lf     修改后的授课学时:", find->time_teach);
  scanf("%s", &temp);
  while (getchar() != '\n');
  if (strcmp(temp, "0") != 0)
  find->time_teach = atof(temp);
 
  printf("\t\t原实验或上机学时:%lf     修改后的实验或上机学时:", find->time_exp);
  scanf("%s", &temp);
  while (getchar() != '\n');
  if (strcmp(temp, "0") != 0)
  find->time_exp = atof(temp);
 
  printf("\t\t原课程学分:%lf     修改后的课程学分:", find->score);
  scanf("%s", &temp);
  while (getchar() != '\n');
  if (strcmp(temp, "0") != 0)
  find->score = atof(temp);
 
  printf("\t\t原能容纳学生总数:%d     修改后的能容纳学生总数:", find->stu_max);
  scanf("%s", &temp);
  while (getchar() != '\n');
  if (strcmp(temp, "0") != 0)
  find->stu_max = atoi(temp);
 
  printf("\t\t修改完成!\n\n");
 }
 }
 
 store_cour(cour_head);
}
 
void print_all()
{
 while (1)
 {
 printf("\n\t\t选择操作类型: [1]打印所有学生信息  [2]打印所有课程信息 [0]返回主菜单:");
 int input = 0;
 scanf("%d", &input);
 while (getchar() != '\n');
 if (input == 1)
 {
  printf("\n\t\t学生总数:%d", link_count(stu_head));
  student_showall(stu_head);
 }
 else if (input == 2)
 {
  printf("\n\t\t课程总数:%d\n", link_count(cour_head));
  courseshowall_man(cour_head);
 }
 else if (input == 0)
  break;
 else
  printf("\n\t\t####输入错误!请重新输入!#####\n");
 }
}
 
void man_modifyKey()
{
 printf("\t\t******请输入原密码(10位):");
 char input[20];
 scanf("%s", input);
 while (getchar() != '\n');
 
 FILE *fp;
 if ((fp = fopen(MAN_F, "r")) == NULL)
 {
 printf("\t\t-------- 无法打开文件:MAN_F\n");
 exit(0);
 }
 char keyOld[11];
 fread(keyOld, 10, 1, fp);
 keyOld[10] = '\0';
 if (strcmp(keyOld, input) == 0)//修改
 {
 fclose(fp);
 char new1[100];
 char new2[100];
 while (1)
 {
  printf("\t\t*******请输入新密码(10位):");
  scanf("%s", new1);
  while (getchar() != '\n');
  printf("\t\t******请再次确认新密码(10位):");
  scanf("%s", new2);
  while (getchar() != '\n');
  if (keyexam(new1, new2) == 1)
  {
  fp = fopen(MAN_F, "w");
  fwrite(new1, 10, 1, fp);
  fclose(fp);
  printf("\n\t\t------密码修改成功!\n");
  break;
  }
  else
  printf("\t\t####前后密码不一致,请重新输入!####\n");
 }
 }
 else
 {
 fclose(fp);
 printf("\t\t####原密码输入错误,请重新选择操作类型####\n");
 }
}
 
void man_backups_recover()
{
 printf("\t\t*****[1]数据备份 [2]数据恢复 [3]取消\n");
 printf("\t\t*****选择操作类型:");
 int input = 0;
 scanf("%d", &input);
 while (getchar() != '\n');
 if (input == 1)
 {
 FILE *fp_source;
 FILE *fp_destination;
 {//课程信息备份
  if ((fp_source = fopen(COUR_F, "r")) == NULL)
  {
  printf("\t\t##课程数据备份失败:无法找到COUR_F文件!##\n");
  exit(0);
  }
  fp_destination = fopen(COUR_F_BACKUP, "w");
  char temp;
  int count = 0;
  while (!feof(fp_source))
  {
  if (fread(&temp, 1, 1, fp_source))
   count++;
  }
  rewind(fp_source);
  for (int i = 0; i < count; i++)
  {
  fread(&temp, 1, 1, fp_source);
  fwrite(&temp, 1, 1, fp_destination);
  }
  fclose(fp_destination);
  fclose(fp_source);
 }
 {//学生信息备份
  if ((fp_source = fopen(STU_F, "r")) == NULL)
  {
  printf("\t\t##学生数据备份失败:无法找到STU_F文件!##\n");
  exit(0);
  }
  fp_destination = fopen(STU_F_BACKUP, "w");
  char temp;
  int count = 0;
  while (!feof(fp_source))
  {
  if (fread(&temp, 1, 1, fp_source))
   count++;
  }
  rewind(fp_source);
  for (int i = 0; i < count; i++)
  {
  fread(&temp, 1, 1, fp_source);
  fwrite(&temp, 1, 1, fp_destination);
  }
  fclose(fp_destination);
  fclose(fp_source);
 }
 {//管理员信息备份
  if ((fp_source = fopen(MAN_F, "r")) == NULL)
  {
  printf("\t\t##管理员数据备份失败:无法找到MAN_F文件!##\n");
  exit(0);
  }
  fp_destination = fopen(MAN_F_BACKUP, "w");
  char temp;
  for (int i = 0; i < 10; i++)
  {
  fread(&temp, 1, 1, fp_source);
  fwrite(&temp, 1, 1, fp_destination);
  }
  fclose(fp_destination);
  fclose(fp_source);
 }
 printf("\n\t\t所有数据已经备份完毕!备份目录为C:\ stu_cour_info_system\backup\n");
 }
 else if (input == 2)
 {
 printf("\t\t选择恢复类型:[1]课程数据  [2]学生数据 [3]管理员数据:");
 int in = 0;
 scanf("%d", &in);
 while (getchar() != '\n');
 FILE *fp_source;
 FILE *fp_destination;
 if (in == 1)//course information recover
 //课程信息恢复
  if ((fp_source = fopen(COUR_F_BACKUP, "r")) == NULL)
  {
  printf("\t\t###课程信息恢复失败!未能找到C:\\stu_cour_info_system\\backup\\course_back.txt###\n");
  exit(0);
  }
  fp_destination = fopen(COUR_F, "w");
  char temp;
  int count = 0;
  while (!feof(fp_source))
  {
  if (fread(&temp, 1, 1, fp_source))
   count++;
  }
  rewind(fp_source);
  for (int i = 0; i < count; i++)
  {
  fread(&temp, 1, 1, fp_source);
  fwrite(&temp, 1, 1, fp_destination);
  }
  fclose(fp_destination);
  fclose(fp_source);
  printf("\n\t\t课程信息恢复成功!\n");
  cour_head = load_cour();
  cour_tail = locate_end(cour_head);
 }
 else if (in == 2)//student information recover
 { //学生信息恢复
  if ((fp_source = fopen(STU_F_BACKUP, "r")) == NULL)
  {
  printf("\t\t###学生信息恢复失败!未能找到C:\\stu_cour_info_system\\backup\\student_back!###\n");
  exit(0);
  }
  fp_destination = fopen(STU_F, "w");
  char temp;
  int count = 0;
  while (!feof(fp_source))
  {
  if (fread(&temp, 1, 1, fp_source))
   count++;
  }
  rewind(fp_source);
  for (int i = 0; i < count; i++)
  {
  fread(&temp, 1, 1, fp_source);
  fwrite(&temp, 1, 1, fp_destination);
  }
  fclose(fp_destination);
  fclose(fp_source);
  printf("\n\t\t学生数据恢复成功!\n");
  stu_head = load_stu();
  stu_tail = locate_end(stu_head);
 }
 else if (in == 3)//manager information recover
 {
  //恢复管理员数据
  if ((fp_source = fopen(MAN_F_BACKUP, "r")) == NULL)
  {
  printf("\t\t###管理员数据恢复失败!未能找到C:\\stu_cour_info_system\\backup\\course_back\n");
  exit(0);
  }
  fp_destination = fopen(MAN_F, "w");
  char temp;
  for (int i = 0; i < 10; i++)
  {
  fread(&temp, 1, 1, fp_source);
  fwrite(&temp, 1, 1, fp_destination);
  }
  fclose(fp_destination);
  fclose(fp_source);
  printf("\n\t\t管理员数据恢复成功!\n");
 }
 else
  printf("\t\t###输入错误!###\n");
 }
 else if (input == 3)
 ;
 else
 printf("\t\t###输入错误,请重新输入!####\n");
}
 
void man_search_stu(student *head)
{
 while (1)
 {
 printf("\n\t\t请输入学号或姓名进行查找,返回上级菜单请输入0000:");
 char input[50];
 scanf("%s", input);
 while (getchar() != '\n');
 if (strcmp(input, "0000") == 0)
  break;
 
 student* p_stu;
 if ((input[0] >= 48) && (input[0] <= 57))
  p_stu = studentnamefind_num(head, input);
 else
  p_stu = studentnamefind_char(head, input);
 
 if (p_stu == stu_tail)
 {
  printf("\n\t\t#####没有该学生的信息,请重新输入!#####/n");
  continue;
 }
 
 if (p_stu == NULL)
  p_stu = head;
 else
  p_stu = p_stu->next;
 
 printf("\n\t\t该学生信息如下:");
 student_showone(p_stu);
 }
}
 
void courseshowone_man(course *ad)
{
 if (ad == NULL)
 printf("无课程");
 else
 {
 printf("\n\t\t------------------------------------------------------");
 printf("\n\t\t课程编号:%s\n", ad->num);
 printf("\t\t课程名称:%s\n", ad->name);
 printf("\t\t课程性质:%s\n", ad->nature);
 printf("\t\t开课学期:%s\n", ad->term);
 printf("\t\t总学时:%lf\n", ad->time_all);
 printf("\t\t授课学时:%lf\n", ad->time_teach);
 printf("\t\t实验或上机学时:%lf\n", ad->time_exp);
 printf("\t\t学分:%lf\n", ad->score);
 printf("\t\t总容纳学生人数:%d\n", ad->stu_max);
 printf("\t\t已选学生人数:%d\n", ad->stu_sum);
 printf("\t\t已选学生:\n");
 if (ad->stu_sum == 0)
  printf("\t\t没有人选该课程\n");
 else
  for (int i = 0; i <ad->stu_sum; i++)
  {
  if (i % 5 == 0)
   printf("\t\t");
  student* temp = studentnamefind_num(stu_head, ad->stu[i]);
  if (temp == NULL)
   temp = stu_head;
  else
   temp = temp->next;
  printf("[%d] %s", i + 1, temp->name);
  if (i > 0 && i % 5 == 0)
   printf("\n");
  }
 printf("\n\t\t------------------------------------------------------");
 }
}
 
void courseshowall_man(course *head)
{
 
 course *p;
 p = head;
 if (p == NULL)
 {
 printf("\t\t无课程\n");
 return;
 }
 while (p != NULL)
 {
 courseshowone_man(p);
 p = p->next;
 }
}

studetn.cpp

?
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
#include<stdio.h>
#include<string.h>
#include"all.h"
#include<stdlib.h>
#include<malloc.h>
#include<ctype.h>
 
extern student* stu_head;
extern course* cour_head;
extern course *cour_tail;
extern student *stu_tail;// 这四个指针变量在main.cpp中已经声明为全局变量
 
student* stu_login(student* head)
{
 student* copy_head = head;
 char input[100];
 printf("\t\t*******请输入学号:");
 scanf("%s", input);
 while (getchar() != '\n');
 student* temp;
 temp = studentnamefind_num(head, input);
 if (temp == NULL)//the first student
 return copy_head;
 else if ((temp != NULL) && (temp->next == NULL))//no such a student
 return NULL;
 else
 return temp->next;
}
 
int stu_menu()
{
 printf("\n\t\t~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~学生菜单~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
 printf("\n\t\t---[1]:打印课程信息");
 printf("\n\t\t---[2]:查找课程信息");
 printf("\n\t\t---[3]:选择新的课程");
 printf("\n\t\t---[4]:删除已选课程");
 printf("\n\t\t---[5]:查看个人信息");
 printf("\n\t\t---[6]:修改登陆密码");
 printf("\n\t\t---[0]:注销");
 printf("\n\n\t\t---请从<0-6>中选择操作类型:");
 int n = input_limit0(6);
 return n;
}
 
void courseshow_nature(course *head)
{
 
 course *p;
 char ad[MAXN];
 while (true)
 {
 int flag = 0, sum = 0;
 p = head;
 printf("\t\t请输入要查找课程的性质,取消查找请输入0000:");
 scanf("%s", ad);
 while (getchar() != '\n');
 if (strcmp(ad, "0000") == 0)
  break;
 while (p != NULL)
 {
  if (strcmp(ad, p->nature) == 0)
  {
  course_showone(p);
  flag = 1;
  sum++;
  }
  p = p->next;
 }
 if (flag == 0)
  printf("\n\t\t没有该课程!####");
 }
 return;
}
 
void courseshow_term(course *head)
{
 
 course *p;
 char ad[MAXN];
 while (true)
 {
 int flag = 0, sum = 0;
 p = head;
 printf("\t\t请输入要查找课程的开课学期,取消查找请输入0000:");
 scanf("%s", ad);
 while (getchar() != '\n');
 if (strcmp(ad, "0000") == 0)
  break;
 while (p != NULL)
 {
  if (strcmp(ad, p->term) == 0)
  {
  course_showone(p);
  flag = 1;
  sum++;
  }
  p = p->next;
 }
 if (flag == 0)
  printf("\n\t\t#####没有该课程!#####");
 }
 return;
}
 
void coursechoose( course* head, student* stu)//选课函数
{
 if (stu->score_sel <stu->score_all )
 printf("\n\t\t你的总学分少于%lf,赶快去选课吧!\n", stu->score_all);
 while (1)
 {
 printf("\n\t\t请输入课程的编号或名称进行选课,取消选课请输入0000:");
 char input[50];
 scanf("%s", input);
 while(getchar()!='\n');
 if (strcmp(input, "0000")==0)
  break;
 course* find = NULL;
 if ((input[0] >= 48) && (input[0] <= 57))
  find = coursenumfind_num(head, input);
 else
  find = coursenamefind_char(head, input);
 
 if (find == cour_tail)
 {
  printf("\n\t\t#####该课程不存在!请重新输入#####\n");
  continue;
 }
 else if (find == NULL)
  find = head;
 else
  find = find->next;
 
 if (find->stu_sum == find->stu_max)
  printf("\n\t\t####该课程人数已满,无法选择!#####\n");
 else
 {
  int judge = 0;
  for (int i = 0; i < stu->course_sum; i++)
  {
  if (strcmp(stu->course[i], find->num)==0)
  {judge = 1; break;}
  }
  if (judge == 1)
  {
  printf("\n\t\t####该课程已经选择过了!####\n");
  continue;
  }
  else
  {
  stu->course_sum++;
  strcpy(stu->course[stu->course_sum - 1], find->num);
  stu->score_sel += find->score;
 
  find->stu_sum++;
  strcpy(find->stu[find->stu_sum - 1], stu->num);
  printf("\n\t\t该课程选择成功!\n");
  }
 }
 
 }
 
 store_cour(cour_head);
 store_stu(stu_head);
}
 
void coursenumfindtip(course *head)
{
 char buf[MAXN];
 course *result;
 while (true)
 {
 
 printf("\t\t请输入要查找课程的编号,取消查找请输入0000:");
 scanf("%s", buf);
 while (getchar() != '\n');
 if (strcmp(buf, "0000") == 0)
  break;
 result = coursenumfind_num(head, buf);
 if (result != cour_tail)
 {
  if (result == NULL)
  result = head;
  else
  result = result->next;
  course_showone(result);
 }
 else
  printf("\t\t#####没有该课程!#####\n");
 }
}
 
void coursenamefindtip(course *head)
{
 char buf[MAXN];
 course *result;
 while (1)
 {
 printf("\t\t请输入要查找课程的名称,取消查找请输入0000:");
 scanf("%s", buf);
 while (getchar() != '\n');
 if (strcmp(buf, "0000") == 0)
  break;
 result = coursenamefind_char(head, buf);
 if (result != cour_tail)
 {
  if (result == NULL)
  result = head;
  else
  result = result->next;
  course_showone(result);
 }
 else
  printf("\t\t#####无所查找的课程!#####\n");
 }
}
 
void stu_dele_cour( course * head, student * stu)
{
 while (1)
 {
 printf("\n\t\t请输入需要删除课程的编号,返回上级菜单请输入0000:");
 char input[50];
 scanf("%s", input);
 while (getchar() != '\n');
 if (strcmp(input, "0000") == 0)
  break;
 int i = 0, result = -1;
 
 /*删除该学生记录中选课的信息*/
 for (; i < stu->course_sum; i++)
 {
  if (strcmp(input, stu->course[i]) == 0)
  { result = i; break; }
 }
 if (result == -1)
  {printf("\n\t\t####你没有选择这门课程!请重新输入!");continue;}
 strcpy(stu->course[result], stu->course[stu->course_sum - 1]);
 stu->course_sum--;  
 
 course* find= coursenumfind_num(head, input);
 if (find == NULL)
  find = head;
 else
  find =find->next;
 
 /*删除该课程记录中学生的信息*/
 i = 0, result = 0;
 for (; i < find->stu_sum; i++)
 {
  if(strcmp(input,find->stu[i])==0)
  { result = i; break;}
 }
 strcpy(find->stu[result], find->stu[find->stu_sum - 1]);
 find->stu_sum --;                           
 
 printf("\n\t\t课程删除成功!\n");
 }
 
 store_stu(stu_head);
 store_cour(cour_head);
}
 
void stu_modifyKey(student* stu)
{
 printf("\t\t******请输入原密码(8位):");
 char input[20];
 scanf("%s", input);
 while (getchar() != '\n');
 
 char keyOld[10];
 strcpy(keyOld, stu->password);
 if (keyexam(keyOld, input) == 1)//修改
 {
 char new1[100];
 char new2[100];
 while (1)
 {
  printf("\t\t*******请输入新密码(8位):");
  scanf("%s", new1);
  while (getchar() != '\n');
  printf("\t\t******请再次确认新密码(8位):");
  scanf("%s", new2);
  while (getchar() != '\n');
  if (keyexam(new1, new2) == 1)
  {
  strcpy(stu->password, new1);
  store_stu(stu_head);
  printf("\n\t\t------密码修改成功!\n");
  break;
  }
  else
  printf("\t\t####前后密码不一致,请重新输入!####\n");
 }
 }
 else
 printf("\t\t####原密码输入错误,请重新选择操作类型####\n");
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。

原文链接:https://blog.csdn.net/qq_40605465/article/details/79717890

延伸 · 阅读

精彩推荐
  • C/C++C语言实现双人五子棋游戏

    C语言实现双人五子棋游戏

    这篇文章主要为大家详细介绍了C语言实现双人五子棋游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    两片空白7312021-11-12
  • C/C++OpenCV实现拼接图像的简单方法

    OpenCV实现拼接图像的简单方法

    这篇文章主要为大家详细介绍了OpenCV实现拼接图像的简单方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    iteye_183805102021-07-29
  • C/C++c/c++内存分配大小实例讲解

    c/c++内存分配大小实例讲解

    在本篇文章里小编给大家整理了一篇关于c/c++内存分配大小实例讲解内容,有需要的朋友们可以跟着学习参考下。...

    jihite5172022-02-22
  • C/C++C语言main函数的三种形式实例详解

    C语言main函数的三种形式实例详解

    这篇文章主要介绍了 C语言main函数的三种形式实例详解的相关资料,需要的朋友可以参考下...

    ieearth6912021-05-16
  • C/C++c/c++实现获取域名的IP地址

    c/c++实现获取域名的IP地址

    本文给大家汇总介绍了使用c/c++实现获取域名的IP地址的几种方法以及这些方法的核心函数gethostbyname的详细用法,非常的实用,有需要的小伙伴可以参考下...

    C++教程网10262021-03-16
  • C/C++关于C语言中E-R图的详解

    关于C语言中E-R图的详解

    今天小编就为大家分享一篇关于关于C语言中E-R图的详解,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看...

    Struggler095962021-07-12
  • C/C++深入C++拷贝构造函数的总结详解

    深入C++拷贝构造函数的总结详解

    本篇文章是对C++中拷贝构造函数进行了总结与介绍。需要的朋友参考下...

    C++教程网5182020-11-30
  • C/C++使用C++制作简单的web服务器(续)

    使用C++制作简单的web服务器(续)

    本文承接上文《使用C++制作简单的web服务器》,把web服务器做的功能稍微强大些,主要增加的功能是从文件中读取网页并返回给客户端,而不是把网页代码...

    C++教程网5492021-02-22