这是一个简单的学生管理程序,记录了四个不同版本

1.第一次学生管理程序(结构体实现):

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

#define _CRT_SECURE_NO_WARNINGS 1//防止scanf报错
#include<stdio.h>
#include<string.h>
typedef struct STUDENTS {//主结构体
int number;
char name[100];
int sex;
union stu {//联合体
struct student {
unsigned int year:11;
unsigned int month:4;
unsigned int day:5;
}birthday;
int date;
}STU;
int score[4];
}STUDENT;
enum types {//枚举类型
男 = 0,
女 =1
};

void Input(STUDENT student[],int n);//输入函数
void Search(char name[], STUDENT student[], int n);//查找函数
void Average(STUDENT student[],int n);//平均成绩和及格率函数
void Comparemin(STUDENT student[], int n);//最小年龄显示函数
int compare(char names[], STUDENT student[100], int n);//匹配字符串的函数
void trans1(STUDENT student[], int n);//联合体中两成员的值互化,下同
void trans2(STUDENT student[], int n);
int main()
{
STUDENT student[100];
int n, chose,func;
char names[100];
part1:printf("请先输入班级学生信息,输入1跳转: ");
scanf("%d", &chose);
rewind(stdin);
if (chose == 1) {
printf("请输入班级人数:");
scanf("%d", &n);
Input(student, n);
}
else if (chose != 1) {
printf("输入错误!,请重新输入\n");
goto part1;
}
printf("请选择你要使用的功能:\n");
printf("1.查找学生信息\n");
printf("2.统计某科目的平均成绩和及格率\n");
printf("3.查找年龄最小的学生信息\n");
scanf("%d", &func);
switch (func)
{
case 1:
printf("请输入学生姓名 ");
rewind(stdin);
gets(names);
Search(names, student, n);
break;
case 2:
Average(student, n);
break;
case 3:
Comparemin(student, n);
break;
}
return 0;
}
void Input(STUDENT student[100], int n) {//输入函数
int i,j;
printf("请依次输入学号:");
for (i = 0; i < n; i++)
scanf("%d",&student[i].number);
printf("请依次输入学生姓名:");
for (i = 0; i < n; i++)
scanf("%s", student[i].name);
printf("请依次输入学生的性别(男:0女:1):");
for (i = 0; i < n; i++)
scanf("%d", &student[i].sex);
printf("请依次输入学生出生年: 月: 日:\n");
for (i = 0; i < n; i++) {
int year, month, day;
scanf("%d%d%d", &year, &month, &day);
student[i].STU.birthday.year = year;
student[i].STU.birthday.month =month;
student[i].STU.birthday.day = day;
}
printf("请依次输入学生的语文 数学 英语 理综成绩:\n");
for (i = 0; i < n; i++) {
for (j = 0; j < 4; j++) {
scanf("%d", &student[i].score[j]);
}
}
}
void Search(char names[], STUDENT student[], int n)//查找函数
{
int a;
a = compare(names, student, n);
if (a!=-1){
printf("您输入的学生信息如下:\n");
printf("姓名: %s\n", student[a].name);
printf("学号: %d\n", student[a].number);
if (student[a].sex == 0)
printf("性别: 男\n");
else if (student[a].sex == 1)
printf("性别: 女\n");
printf("出生日期: %d%02d%02d\n", student[a].STU.birthday.year, student[a].STU.birthday.month, student[a].STU.birthday.day);
printf("该学生的各科成绩为\n语文:%d\n", student[a].score[0]);
printf("数学:%d\n", student[a].score[1]);
printf("英语:%d\n", student[a].score[2]);
printf("理综:%d\n", student[a].score[3]);
}
else if(compare(names, student, n)==-1)
printf("无该学生信息\n");
}
int compare(char names[] ,STUDENT student[], int n) {//名字匹配
int i,flag,j;
for (i = 0; i < n; i++)
{
for (j = 0; j < strlen(names); j++) {
if (names[j] == student[i].name[j])
flag = 1;
else {
flag = 0;
break;
}
}
if (flag == 1)
return i;
}
if (flag == 0)
return -1;
}
void Average(STUDENT student[], int n)//及格率和平均成绩
{
int subject,i;
double avg,pass,sum=0;
int a=0, b=0;
printf("请输入你想统计的科目:\n1.语文\n2.数学\n3.英语\n4.理综\n");
scanf("%d",&subject);
if (subject == 1){
for (i = 0; i < n; i++){
sum += student[i].score[0];}
for (i = 0; i < n;i++)
{if (student[i].score[0] >= 60)
a++;
else if (student[i].score[0] < 60)
b++;}
avg = sum / n;
pass = (double)a / (a + b);
printf("语文的平均成绩为:%.2lf\n语文的及格率为%%%.2lf", avg, pass);}
else if (subject == 2) {
for (i = 0; i < n; i++) {
sum += student[i].score[1];}
for (i = 0; i < n; i++){
if (student[i].score[1] >= 60)
a++;
else if (student[i].score[1] < 60)
b++;}
avg = sum / n;
pass = (double)a / (a + b);
printf("数学的平均成绩为:%.2lf\n数学的及格率为%%%.2lf", avg, pass);}
else if (subject == 3) {
for (i = 0; i < n; i++) {
sum += student[i].score[2];}
for (i = 0; i < n; i++){
if (student[i].score[2] >= 60)
a++;
else if (student[i].score[2] < 60)
b++;}
avg = sum / n;
pass = (double)a / (a + b);
printf("英语的平均成绩为:%.2lf\n英语的及格率为%%%.2lf", avg, pass);}
else if (subject == 4) {
for (i = 0; i < n; i++) {
sum += student[i].score[3];}
for (i = 0; i < n; i++){
if (student[i].score[3] >= 60)
a++;
else if (student[i].score[3] < 60)
b++;}
avg = sum / n;
pass = (double)a / (a + b);
printf("理综的平均成绩为:%.2lf\n理综的及格率为%%%.2lf", avg, pass);}
}
void Comparemin(STUDENT student[], int n)
{
trans1(student, n);
int min=0,i;
for (i =0; i < n;i++)//找出年龄最小的学生对应的出生日期
{
if (min < student[i].STU.date)
min = student[i].STU.date;

}

for (i = 0; i < n; i++)
{
if (min == student[i].STU.date)//学生匹配
{
break;
}
}
trans2(student, n);
printf("年龄最小的学生信息如下:\n");
printf("姓名: %s\n", student[i].name);
printf("学号: %d\n", student[i].number);
if (student[i].sex == 0)
printf("性别: 男\n");
else if (student[i].sex == 1)
printf("性别: 女\n");
printf("出生日期: %d%02d%02d\n", student[i].STU.birthday.year, student[i].STU.birthday.month, student[i].STU.birthday.day);
printf("该学生的各科成绩为\n语文:%d\n", student[i].score[0]);
printf("数学:%d\n", student[i].score[1]);
printf("英语:%d\n", student[i].score[2]);
printf("理综:%d\n", student[i].score[3]);
}

void trans1(STUDENT student[], int n)//联合体中两成员值的转换
{
int i;
for (i = 0; i < n; i++)
{
student[i].STU.date = (student[i].STU.birthday.year)* 10000 + (student[i].STU.birthday.month) * 100 + student[i].STU.birthday.day;
}
}
void trans2(STUDENT student[], int n)//联合体中两成员值的转换
{
int i,a;
for (i = 0; i < n; i++)
{
a = student[i].STU.date;
student[i].STU.birthday.year = a / 10000;
student[i].STU.birthday.month = (a%10000)/100;
student[i].STU.birthday.day = a % 100;
}
}

2.第二次学生管理程序(链表实现)

main.c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include"function.h"

int main()
{
FILE* p;
p = fopen("student", "r");
if (p == NULL)
{
printf("加载数据失败,开始录入学生数据:\n");
Input();
}
else
{
fclose(p);
read();
}
menu();
}

function.c

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
#define _CRT_SECURE_NO_WARNINGS 1//防止scanf报错
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
struct STUDENT {//主结构体
int number;
char name[50];
int sex;
union stu {//联合体
struct birthday {
unsigned int day : 5;
unsigned int month : 4;
unsigned int year : 11;
}stus;
int date;
}STU;
int score[4];
struct STUDENT* next;
};
struct STUDENT* head = NULL;
struct STUDENT* student = NULL, * current = NULL;//创建链表结点

enum types {
男 = 0,
女 = 1
};
void Input() {
int i;
char temp[50];
while (1)
{
current = (struct STUDENT*)malloc(sizeof(struct STUDENT));
if (current != NULL) {
if (head == NULL)
head = current;
else
student->next = current;
current->next = NULL;
puts("请输入学生姓名: ");
gets(temp);
strcpy(current->name, temp);
puts("请输入该学生的学号: ");
scanf("%d", &current->number);
puts("请输入该学生的性别(男:0女:1): ");
scanf("%d", &current->sex);
puts("请输入学生的出生日期年 月 日: ");
int year, month, day;
scanf("%d %d %d", &year, &month, &day);
current->STU.stus.year = year;
current->STU.stus.month = month;
current->STU.stus.day = day;
puts("请依次输入学生的语文 数学 英语 理综成绩: ");
scanf("%d %d %d %d", &current->score[0], &current->score[1], &current->score[2], &current->score[3]);
student = current;
rewind(stdin);
printf("继续输入请按1,输入完成请按2:");
scanf("%d", &i);
getchar();
if (i == 1)
continue;
else
break;
}
}
}
void Find() {

puts("所有学生的信息如下:\n");
current = head;
while (current != NULL)
{
printf("学生姓名:%s\n", current->name);
printf("学号:%d\n", current->number);
if (current->sex == 0)
printf("性别: 男\n");
else if (current->sex == 1)
printf("性别: 女\n");
printf("出生日期:%d%02d%02d\n", current->STU.stus.year, current->STU.stus.month, current->STU.stus.day);
printf("该学生的各科成绩为\n语文:%d\n", current->score[0]);
printf("数学:%d\n", current->score[1]);
printf("英语:%d\n", current->score[2]);
printf("理综:%d\n", current->score[3]);
current = current->next;
}
}
void Search() {
char names[50];
printf("请输入学生的姓名: ");
scanf("%s", names);
current = head;
while (current != NULL) {
if (match(names, current) == 1)//匹配名字
{
printf("您要查找的学生信息如下:\n");
printf("姓名: %s\n", current->name);
printf("学号: %d\n", current->number);
if (current->sex == 0) {
printf("性别: 男\n");
}
else if (current->sex == 1)
{
printf("性别: 女\n");
}
printf("出生日期:%4d%02d%02d\n", current->STU.stus.year, current->STU.stus.month, current->STU.stus.day);
printf("该学生的各科成绩为\n语文:%d\n", current->score[0]);
printf("数学:%d\n", current->score[1]);
printf("英语:%d\n", current->score[2]);
printf("理综:%d\n", current->score[3]);
break;
}
current = current->next;
}
if (current == NULL)
printf("没有该学生信息\n");
}


void Average()
{
int subject, n = 0;//n用于统计结点个数
double avg = 0, sum = 0;
current = head;
printf("请输入你想统计的科目:\n1.语文\n2.数学\n3.英语\n4.理综\n");
scanf("%d", &subject);
if (subject == 1) {
while (current != NULL)
{
sum += current->score[0];
current = current->next;
n++;
}
avg = sum / n;
printf("语文的平均成绩为:%.2lf", avg);
}
else if (subject == 2) {
while (current != NULL)
{
sum += current->score[2];
current = current->next;
n++;
}
avg = sum / n;
printf("数学的平均成绩为:%.2lf", avg);
}
else if (subject == 3) {
while (current != NULL)
{
sum += current->score[2];
current = current->next;
n++;
}
avg = sum / n;
printf("英语的平均成绩为:%.2lf\n", avg);
}
else if (subject == 4) {
while (current != NULL)
{
sum += current->score[3];
current = current->next;
n++;
}
avg = sum / n;
printf("理综的平均成绩为:%.2lf", avg);
}
}

int match(char names[], struct STUDENT* current)
{
int flag, i;
for (i = 0; i < strlen(names); i++)
{
if (current->name[i] == names[i])
{
flag = 1;
}
else if (current->name[i] != names[i])
{
flag = 0;
break;
}
}
if (flag == 1)
return 1;
else if (flag == 0)
return 0;
}
void preserve()
{
current = head;
FILE* p1;
p1 = fopen("student", "w");
if (p1 == NULL)
{
printf("文件打开失败");
exit(1);
}
while (current != NULL)
{
fprintf(p1, "%s\n", current->name);
fprintf(p1, "%d\n", current->number);
fprintf(p1, "%d\n", current->sex);
fprintf(p1, "%4d%02d%02d\n", current->STU.stus.year, current->STU.stus.month, current->STU.stus.day);
fprintf(p1, "%d\n", current->score[0]);
fprintf(p1, "%d\n", current->score[1]);
fprintf(p1, "%d\n", current->score[2]);
fprintf(p1, "%d\n", current->score[3]);
current = current->next;
}

if (fclose(p1) != 0)
printf("文件关闭失败");
else
printf("保存数据成功,文件关闭成功\n");
}
void read()
{
FILE* p2;
p2 = fopen("student", "r");
if (p2 == NULL) {
printf("打开文件失败");
exit(1);
}
while (!feof(p2))//读取到文件结尾
{
current = (struct STUDENT*)malloc(sizeof(struct STUDENT));
if (head == NULL)
head = current;
else
student->next = current;
current->next = NULL;
fscanf(p2, "%s\n", current->name);
fscanf(p2, "%d\n", &current->number);
fscanf(p2, "%d\n", &current->sex);
int year, month, day;
fscanf(p2, "%4d%02d%02d\n", &year, &month, &day);。
current->STU.stus.year = year;
current->STU.stus.month = month;
current->STU.stus.day = day;//设置位宽后的处理
fscanf(p2, "%d\n", &current->score[0]);
fscanf(p2, "%d\n", &current->score[1]);
fscanf(p2, "%d\n", &current->score[2]);
fscanf(p2, "%d\n", &current->score[3]);
student = current;

}
if (fclose(p2) != 0)
printf("文件关闭失败");
else
printf("学生数据加载成功\n");
}
void SearchID() {
int a, b = 0;
printf("请输入学生的学号: ");
scanf("%d", &a);
current = head;
while (current != NULL)
{
if (a == current->number)
{
break;
}
current = current->next;
b++;
}
if (current == NULL)//到达最后一个结点的判断条件
printf("无该学生信息");
else {
printf("该学生信息如下:\n");
printf("姓名: %s\n", current->name);
printf("学号: %d\n", current->number);
if (current->sex == 0) {
printf("性别: 男\n");
}
else if (current->sex == 1)
{
printf("性别: 女\n");
}
printf("出生日期:%4d%02d%02d\n", current->STU.stus.year, current->STU.stus.month, current->STU.stus.day);
printf("该学生的各科成绩为\n语文:%d\n", current->score[0]);
printf("数学:%d\n", current->score[1]);
printf("英语:%d\n", current->score[2]);
printf("理综:%d\n", current->score[3]);
}
}
void DeleteID()
{
int a, flag;
printf("请输入删除学生的学号: ");
scanf("%d", &a);
current = head;
while (current->next != NULL)
{
if (current->next->next != NULL) {
if (current->next->number == a)
{
current->next = current->next->next;
flag = 1;//删除改链表结点
break;
}
}
else//删除链表尾结点
{
if (current->next->number == a) {
current->next = NULL;
flag = 1;
break;
}
}
current = current->next;
flag = 0;
}
if (flag == 1)
printf("删除成功");
else
printf("删除失败,找不到该学生");

}
void Deletename()
{
char names[50];
int flag;
printf("请输入删除学生的姓名: ");
scanf("%s", names);
current = head;
while (current->next != NULL)
{
if (current->next->next != NULL) {
if (match(names, current) == 1)
{
current->next = current->next->next;//删除列表结点
flag = 0;
break;
}
}
else
{
if (match(names, current->next) == 1) {//单独处理列表尾结点
current->next = NULL;
flag = 0;
break;
}
}
flag = 1;
current = current->next;
}
if (flag == 0)
printf("删除成功");
else {
printf("删除失败,没有该学生信息");
}
}
void menu()
{
int func;
printf("请选择你要使用的功能:\n");
printf("1.查看所有学生\n");
printf("2.姓名查找学生信息\n");
printf("3.学号查找学生信息\n");
printf("4.输入学号删除学生信息\n");
printf("5.输入姓名删除学生信息\n");
printf("6.统计某科目的平均成绩\n");
printf("7.保存学生数据\n");
scanf("%d", &func);
switch (func)
{
case 1:
Find();
break;
case 2:
rewind(stdin);
Search();
break;
case 3:
SearchID();
break;
case 4:
DeleteID();
break;
case 5:
Deletename();
break;
case 6:
Average();
break;
case 7:
preserve();
break;
}
}

3.第三次学生管理程序(类+链表+c++ 实现)

define.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
#include<iostream>
#include<string>
class Student {
private:
int number;
std::string name;
int sex;
union stu {//联合体
struct birthday {
unsigned int day : 5;
unsigned int month : 4;
unsigned int year : 12;
}stus;
int date;
}STU;
int score[4];

public:
Student()//构造函数初始化变量
{
number = 0;
name = "names";
sex = 0;
score[0] = { 0 };
score[1] = { 0 };
score[2] = { 0 };
score[3] = { 0 };
}
Student* next = nullptr;
friend class Classroom;//友元类(使得current能够访问Student类中的私有变量)
};
class Classroom
{
private:
Student* head = nullptr; //指向下一结点
Student* latter = nullptr;
Student* current = nullptr; //c++中用nullptr代表空指针,而NULL当作0使用
public:
void Input();
void Find();
void Search();
void SearchID();
void Average();
void DeleteID();
void Deletename();
void preserve();
void read();
void menu();
};

achieve.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
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<fstream>//用于处理文件输入输出
#include<cstdlib>//为exit()提供原型
#include"define.h"
using namespace std;
void Classroom::Input() {
int i;
while (1)
{
current = new Student;
if (head == nullptr)
head = current;
else
latter->next = current;
current->next = nullptr;
cout << "请输入学生姓名: ";
cin >>current->name;
cout <<"请输入该学生的学号: ";
cin >> current->number;
cout<<"请输入该学生的性别(男:0女:1): ";
cin >> current->sex;
cout<<"请输入学生的出生日期年 月 日: ";
rewind(stdin);
int year, month, day;
cin >> year ;
cin >> month;
cin >> day;
current->STU.stus.year = year;
current->STU.stus.month = month;
current->STU.stus.day = day;
cout<<"请依次输入学生的语文 数学 英语 理综成绩: ";
cin >> current->score[0] >> current->score[1] >> current->score[2] >>current-> score[3];
latter = current ;
cout << "继续输入请按1,输入完成请按2:";
cin >> i;
if (i == 1)
continue;
else
break;
}
}
void Classroom::Find()
{
puts("所有学生的信息如下:\n");
current = head;
while (current != nullptr)
{
cout << "学生姓名: " << current->name << endl;
cout << "学号: " << current->number << endl;
cout << "性别: " << current->sex << endl;
if (current->sex == 0)
cout << "性别: 男" << endl;
else if (current->sex == 1)
cout << "性别: 女" << endl;
cout << "出生日期: " << current->STU.stus.year <<" "<< current->STU.stus.month <<" "<< current->STU.stus.day << endl;
cout << "该学生的各科成绩为: " << endl;
cout << "语文: " << current->score[0] << endl;
cout << "数学: " << current->score[1] << endl;
cout << "英语: " << current->score[2] << endl;
cout << "理综: " << current->score[3] << endl;
current = current->next;
}
}
void Classroom::Search() {
string names;
cout<<"请输入学生的姓名: ";
cin >> names;
current = head;
while (current != nullptr) {
if (names==current->name)//匹配名字
{
cout<<"您要查找的学生信息如下: "<<endl;
cout<<"姓名: "<<current->name<<endl;
cout<<"学号: "<< current->number<<endl;
if (current->sex == 0)
cout << "性别: 男" << endl;
else if (current->sex == 1)
cout << "性别: 女" << endl;
cout << "出生日期: " << current->STU.stus.year << " " << current->STU.stus.month << " " << current->STU.stus.day << endl;
cout << "该学生的各科成绩为: " << endl;
cout << "语文: " << current->score[0] << endl;
cout << "数学: " << current->score[1] << endl;
cout << "英语: " << current->score[2] << endl;
cout << "理综: " << current->score[3] << endl;
break;
}
current = current->next;
}
if (current == nullptr)
cout<<"没有该学生信息\n";
}
void Classroom::SearchID() {
int a, b = 0;
cout << "请输入学生的学号: ";
cin >> a;
current = head;
while (current != nullptr)
{
if (a == current->number)
{
break;
}
current = current->next;
b++;
}
if (current == nullptr)//到达最后一个结点的判断条件
cout << "无该学生信息";
else {
cout << "您要查找的学生信息如下: " << endl;
cout << "姓名: " << current->name << endl;
cout << "学号: " << current->number << endl;
if (current->sex == 0)
cout << "性别: 男" << endl;
else if (current->sex == 1)
cout << "性别: 女" << endl;
cout << "出生日期: " << current->STU.stus.year << " " << current->STU.stus.month << " " << current->STU.stus.day << endl;
cout << "该学生的各科成绩为: " << endl;
cout << "语文: " << current->score[0] << endl;
cout << "数学: " << current->score[1] << endl;
cout << "英语: " << current->score[2] << endl;
cout << "理综: " << current->score[3] << endl;
}
}
void Classroom::Average()
{
int subject, n = 0;//n用于统计结点个数
double avg = 0, sum = 0;
current = head;
cout<<"请输入你想统计的科目:\n1.语文\n2.数学\n3.英语\n4.理综\n";
cin >> subject;
if (subject == 1) {
while (current != nullptr)
{
sum += current->score[0];
current = current->next;
n++;
}
avg = sum / n;
cout<<"语文的平均成绩为: "<< avg;
}
else if (subject == 2) {
while (current != nullptr)
{
sum += current->score[2];
current = current->next;
n++;
}
avg = sum / n;
cout<<"数学的平均成绩为: "<< avg;
}
else if (subject == 3) {
while (current != nullptr)
{
sum += current->score[2];
current = current->next;
n++;
}
avg = sum / n;
cout << "英语的平均成绩为: " << avg;
}
else if (subject == 4) {
while (current != nullptr)
{
sum += current->score[3];
current = current->next;
n++;
}
avg = sum / n;
cout << "理综的平均成绩为: " << avg;
}
}

void Classroom::DeleteID()
{
int a, flag;
cout<<"请输入删除学生的学号: ";
cin >> a;
current = head;
while (current->next != nullptr)
{
if (current->number == a)//删除列表头结点
{
head = current->next;
delete(current);
flag = 1;
break;
}
if (current->next->next != nullptr) {
if (current->next->number == a)
{
current->next = current->next->next;
delete(current->next);
flag = 1;//删除改链表结点
break;
}
}
else//删除链表尾结点
{
if (current->next->number == a) {
current->next = nullptr;
delete(current->next);
flag = 1;
break;
}
}
current = current->next;
flag = 0;

}
if (flag == 1)
cout<<"删除成功";
else
cout <<"删除失败,找不到该学生";
}
void Classroom::Deletename()
{
string names;
int flag;
cout<<"请输入删除学生的姓名: ";
cin >> names;
current = head;
while (current->next != nullptr)
{

if (current->name == names)//删除列表头结点
{
head = current->next;
delete(current);
flag = 0;
break;
}
if (current->next->next != nullptr) {
if (names==current->next->name)
{
delete(current->next);
current->next = current->next->next;//删除列表结点
flag = 0;
break;
}
}
else
{
if (names == current->next->name) {//单独处理列表尾结点
delete(current->next);
current->next = nullptr;
flag = 0;
break;
}
}
flag = 1;
current = current->next;
}
if (flag == 0)
cout << "删除成功";
else {
cout << "删除失败,没有该学生信息";
}
}
void Classroom::preserve()
{
current = head;
ofstream outFile;
outFile.open("student.txt");
if (!outFile.is_open()) {//判断文件是否打开成功,打开成功返回true
cout << "文件打开失败";
exit(1);
}
while (current != nullptr)
{
outFile<<current->name<<endl;
outFile<< current->number << endl;
outFile << current->sex << endl;
outFile << current->STU.stus.year << endl << current->STU.stus.month << endl << current->STU.stus.day << endl;
outFile << current->score[0] << endl;
outFile << current->score[1] << endl;
outFile << current->score[2] << endl;
outFile << current->score[3] << endl;
current = current->next;

}
outFile.close();
cout << "保存成功";
}
void Classroom::read()
{
ifstream inFile;
inFile.open("student.txt");
if (!inFile.is_open())
{
cout << "文件打开失败";
exit(1);
}
while (!inFile.eof())//读取到文件结尾
{
current = new Student;
if (head ==nullptr)
head = current;
else
latter->next = current;
current->next = nullptr;
inFile >> current->name;
inFile >> current->number;
inFile >> current->sex;
int year, month, day;
inFile >> year;
inFile >> month;
inFile >> day;
current->STU.stus.year = year;
current->STU.stus.month = month;
current->STU.stus.day = day;//设置位宽后的处理
inFile >> current->score[0];
inFile >> current->score[1];
inFile >> current->score[2];
inFile >> current->score[3];
latter = current;

}
inFile.close();
cout << "学生数据加载成功\n";
}

main.cpp:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include<iostream>
#include<fstream>
#include"define.h"
Classroom a;//创建Classroom对象(变量),便于调用函数,同时创建的全局变量,具有外部链接,便于菜单调用;
int main()
{
std::ifstream inFile;
inFile.open("student.txt", std::ios::in);//第一个参数为文件名,第二个参数为打开方式,ios::in为只读模式
if (!inFile.is_open())
{
std::cout << "开始录入数据:";
a.Input();
}
else {
inFile.close();
a.read();
std::cout << "数据加载成功" << std::endl;
}
a.menu();
}

menu.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
#include<iostream>
#include"define.h"
void Classroom::menu()
{
int func;
extern Classroom a;//extern引用声明main文件中的a
printf(" **********请选择你要使用的功能: ********** \n");
printf(" **********1.查看所有学生 ********** \n");
printf(" **********2.姓名查找学生信息 ********** \n");
printf(" **********3.学号查找学生信息 ********** \n");
printf(" **********4.输入学号删除学生信息********** \n");
printf(" **********5.输入姓名删除学生信息********** \n");
printf(" **********6.统计某科目的平均成绩********** \n");
printf(" **********7.保存学生数据 ********** \n");
std::cin >> func;
switch (func)
{
case 1:
a.Find();
break;
case 2:
rewind(stdin);
a.Search();
break;
case 3:
a.SearchID();
break;
case 4:
a.DeleteID();
break;
case 5:
a.Deletename();
break;
case 6:
a.Average();
break;
case 7:
a.preserve();
break;
}
}

4.第四个版本在github仓库

5.Base64编码解码

bitset——定义及常用操作

bitset 就相当于一个 只能存储二进制,也就是 0 和 1 的 bool 数组(容器)
但是可以直接当作一个数进行左移右移,取或取反等二进制操作。

如果直接用 bool 数组存储二进制每一位的话,n 位存储复杂度为 O(n),但是用 bitset 的话复杂度会减少到 O(n/32)。

所以一般用二进制状态压缩时就会用 bitset。

使用时引入头文件#include

定义:

对于 bitset 的定义有四种方式:
1、直接定义,每一位初始为0:
bitset<N> name; // 定义长度为 N 的二进制数组,命名为 name;

1
2
bitset<8> b1;
cout << b1 <<endl; // 00000000

2、存储数字的二进制:
bitset<N> name(num); // 定义长度为 N 的二进制数组,命名为 name,将数字 num 的二进制存到其中;

1
2
bitset<8> b2(12); //二进制长度8,将12转化为二进制存到其中。
cout << b2 << endl;

3、存储 01字符串 对应的二进制:
bitset<N> name(string); // 定义长度为 N 的二进制数组,命名为 name,将01串 string 存到其中,长度不够前补 0,长度过长截断

1
2
3
string s = "10010";
bitset<8> b3(s);
cout << b3 << endl;

4、存储 01字符数组 中的二进制:
bitset<N> name(char[]); // 定义长度为 N 的二进制数组,命名为 name,将 01字符数组存到其中,长度不够前补0,长度过长截断

1
2
3
char chs[10] = "10010";
bitset<8> b4(chs);
cout << b4 << endl;

注意:
直接输出 bitset 为正常的二进制,但是遍历所有位置来输出的话就是逆序的:

1
2
3
bitset<8> bs(13);
cout << bs <<endl; //00001101
for(int i=0;i<7;i++) cout<<bs[i]; //10110000

常用操作:

像数字一样进行 取或 或者 左移右移:

1
2
3
4
5
b2 |= b3; //两个二进制数取或操作; 
b2 &= b3; //两个二进制数取与操作;
b2 ^= b3; //取异或;
b2 = ~b2; //取反;
b2 <<= 2; //左移右移;自带函数:

自带函数:

1
2
3
4
5
6
7
8
9
int cnt_1 = b2.count(); //查询二进制数组中,1的个数;
int len = b2.size(); //二进制数组的长度,就是定义的长度;
int test = b2.test(7); //判断第x个位置是0还是1,也就是输出第x个位置,注意逆序;

b2.flip(); //将二进制每一位取反;
b2.flip(3); //将二进制第x位取反;
b2.set(); //将二进制每一位置为1; reset置为0;
b2.set(3); //将第x个位置置为1;

常用操作:

string ss = b2.to_string(); //将二进制数组转化为字符串.

代码实现:

main.c

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
#include<iostream>
#include"main.h"
using namespace std;

int main() {
DATA data,data1;
int choose;
cout<<"选择你想使用的功能(请确保进行操作的文件路径存在):"<<endl;
cout<<"*****1. 编码 *****"<<endl;
cout<<"*****2. 解码 *****"<<endl;
cout<<"*****3.创建编码文件*****"<<endl;
cout<<"*****4.创建解码文件*****"<<endl;
cin >> choose;
switch(choose)
{
case 1:
inFile(data);
transform_2_string(data);
encode_number(data);
transform_string_10(data);
output_encode(data);
outFile_encode(data);
break;
case 2:
inFile(data1);
decode_2_string(data1);
decode_number(data1);
decode_string_10(data1);
output_decode(data1);
outFile_decode(data1);
break;
case 3:
Input_encode(data);
case 4:
Input_decode(data1);
}
return 0;
}

main.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
///
// Created by 柯秋迪 on 2022/11/29.
//

#ifndef UNTITLED2_MAIN_H
#define UNTITLED2_MAIN_H
#include<string>
using namespace std;
struct DATA {
const char aci[64]={'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V',
'W','X','Y','Z','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r',
's','t','u','v','w','x','y','z','0','1','2','3','4','5','6','7','8','9','+','/'};//映射表
string input;
string trans_input;
string a[100];
int b[100];
};
void transform_2_string(DATA &data);
void encode_number(DATA &data);
void transform_string_10(DATA &data);
void output_encode(DATA &data);
void decode_2_string(DATA &data1);
void decode_number(DATA &data1);
void decode_string_10(DATA &data1);
void output_decode(DATA &data1);
void inFile(DATA &data);
void outFile_decode(DATA &data1);
void outFile_encode(DATA &data);
void Input_encode(DATA &data);
void Input_decode(DATA &data1);
#endif //UNTITLED2_MAIN_H

define.c

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
//
// Created by 柯秋迪 on 2022/11/29.
//
#include<iostream>
#include<string>
#include<bitset>
#include<cmath>
#include<fstream>
#include<cstring>
#include"main.h"
unsigned int num;
void transform_2_string(DATA &data){
for(int i=0;i<data.input.size();i++) {
bitset<8>bs(data.input[i]);//将数据转化为二进制储存在bs中
data.trans_input+=bs.to_string();//将bs中的数据转化为字符串
}
}
void encode_number(DATA &data)
{
int j=0;
if(data.trans_input.size()%24==0) {//每一组完全占满的情况
num = data.trans_input.size() / 6;
for (int i = 0; i < num; i++) {
for (; j < data.trans_input.size(); j++) {
data.a[i] += data.trans_input[j];
if (j >= 5) {
if ((j + 1) % 6 == 0) {
j++;
break;
}
}
}
}
}
else{//不完全占满的情况
num = (data.trans_input.size() / 24);
if(num==0)
num=4;
else
num=4*((data.trans_input.size()/24)+1);
for(int i=0;i<num;i++)
{
for(;j<data.trans_input.size();j++)
{
data.a[i]+=data.trans_input[j];
if(j>=5)
{
if((j+1)%6==0)
{
j++;
break;
}
}

}


}
}
for (int i = 0; i < num; i++) {
if (data.a[i].size() < 6) {
size_t n = data.a[i].size();//size()的返回值为size_t/unsigned int类型,用int型接收返回值会警告,返回值为正数
if (!data.a[i].empty()) {
for (int k = 0; k < 6 - n; k++) {
data.a[i].push_back('0');//不能用0,0是数值无法加到字符串后面,0不是字符'0'才是,'0'可加到后面
}
} else
for (int m = 0; m < 6; m++)
{
data.a[i].push_back('0');
}
}
}
}
void transform_string_10(DATA &data){

for(int i=0;i<num;i++)
{
if(data.a[i]!="000000") {
int l = 0;
double sum=0;
for ( int j = data.a[i].size() - 1; j >= 0; j--) {
sum += (data.a[i][l] - 48) * pow(2, j);//
l++;// 字符数字转数值
}
data.b[i] = (int)sum;
}
else
data.b[i]=64;//对等号的单独处理
}
}
void output_encode(DATA& data) {
cout<<"编码后为:";
for (int i = 0; i < num; i++) {
int j=0;
for (; j < 64; j++) {
if (data.b[i] == j) {
cout << data.aci[j];
break;
}
}
if(j==64)//与上方令其为64呼应
cout<<'=';
}
cout<<endl;
}





void decode_2_string(DATA &data1) {

for(int n=0;n<data1.input.size();n++) {
for (int m = 0; m < 64; m++) {
if (data1.input[n] == data1.aci[m]) {
data1.input[n]=(char)m;
break;
} //先将需要解码的字符变为base64中匹配的aci码
}
}

for (int i = 0; i < data1.input.size(); i++) {
if(data1.input[i]!='='){
bitset<6> bs(data1.input[i]);
data1.trans_input += bs.to_string();
}


}
}
void decode_number(DATA &data1) {
int j = 0;
if (data1.trans_input.size() % 8 == 0) {
num = data1.trans_input.size() / 8;
} else {
num = (data1.trans_input.size() / 8) + 1;
}
for (int i = 0; i < num; i++) {
for (; j < data1.trans_input.size(); j++) {
data1.a[i] += data1.trans_input[j];
if (j >= 7) {
if ((j + 1) % 8 == 0) {
j++;
break;
}
}
}
}
for (int i = 0; i < num; i++) {
if (data1.a[i].size() < 8) {
size_t k = 8 - data1.a[i].size();//补齐8位
for (int m = 0; m < k; m++)
data1.a[i].push_back('0');//注意不要写成0了,0为数值不能添加到字符串后面,应为'0'是字符才能放到字符串的后面
}
}
}
void decode_string_10(DATA &data1){
for(int i=0;i<num;i++) {

if (data1.a[i] != "000000") {//为=时就会全为0,当全为0时不会转换
for (int j = 0; j < 8; j++) {
int l = 0;
double sum = 0;
for (int k = data1.a[i].size() - 1; k >= 0; k--, l++) {
sum += (data1.a[i][l] - 48) * pow(2, k);// 字符数字转数值
}
data1.b[i] = (int) sum;
}
}
else
data1.b[i]=64;//对等号的处理防止出现奇怪的字符
}
}
void output_decode(DATA &data1)
{
cout<<"解码后为:";
for(int i=0;i<num;i++)
{
if(data1.b[i]!=64)
printf("%c",data1.b[i]);
}
cout<<endl;
}


void inFile(DATA &data){
string encode_txt;
cout <<"请输入文件路径:";
cin >> encode_txt;
ifstream inFile;
inFile.open(encode_txt,ios::in);//只读模式打开
if(!inFile.is_open())
{
cout << "找不到需要编码的文件,程序已自动结束";
exit(1);
}
inFile >> data.input;
inFile.close();
}

void outFile_decode(DATA &data1)
{
string encode_txt;
cout <<"请输入保存结果的文件路径:";
cin >> encode_txt;
ofstream outFile;
outFile.open(encode_txt);
if(!outFile.is_open())
{
cout << "文件保存失败";
exit(1);
}
for(int i=0;i<num;i++)
{
if(data1.b[i]!=64)
outFile << (char)data1.b[i];
}
outFile.close();
cout << "文件保存成功";
}
void outFile_encode(DATA &data)
{
string encode_txt;
cout <<"请输入保存结果的文件路径:";
cin >> encode_txt;
ofstream outFile;
outFile.open(encode_txt);
if(!outFile.is_open())
{
cout << "文件保存失败";
exit(1);
}
for (int i = 0; i < num; i++) {
int j=0;
for (; j < 64; j++) {
if (data.b[i] == j) {
cout << data.aci[j];
break;
}
}
if(j==64)//与上方令其为64呼应
outFile<<'=';
}
}
void Input_encode(DATA &data) {
cout<<"请输入编码内容:";
cin.get();//吸收回车;
getline(cin,data.input);//此处不用cin,否则会造成有空格的时候,会被截断,下同
transform_2_string(data);
encode_number(data);
transform_string_10(data);
output_encode(data);
outFile_encode(data);
}
void Input_decode(DATA &data1){
cout<<"请输入解码内容:";
cin.get();//吸收回车;
getline(cin,data1.input);
decode_2_string(data1);
decode_number(data1);
decode_string_10(data1);
output_decode(data1);
outFile_decode(data1);
}