题目要求:
任务描述: 写⼀个命令⾏交互式C语⾔程序。该程序需要实现下述菜单功能:
1. 数据存储。 你需要将⼀系列的学⽣期末考试信息进⾏存储(学⽣⼈数不会超过100)。每个学⽣的信息包括:姓名(由 first name 和last name 两部分组成,例如Jingyu LI,first_name = "Jingyu" last_name = "LI") ;学号(12 位数字组成,开头4位为2022、2021、2020);C语⾔成绩(⼀个⼤于等于零的整数);重修信息(学号 2022………为否,其余为是);GPA等级(A+, A, B+, B, C+, C, D, F );班级排名(成绩相同需并列)。其 中,姓名,学号,成绩为输入数据,其余数据需要你计算。 同时,你需要添加⼀些维护数据库的功能 Add(name, id, score): 新增⼀个学⽣的信息; Delete(id): 根据学号删除某个学⽣的信息; Search(id):根据学号查找某个学⽣的信息。
2. 数据处理。 Sort_by_score(): ⽣成根据分数由⾼到低顺序排列学⽣信息的表格
3. 数据加密和解密 char* encrypt(int key): 加密学⽣成绩并返回 char* decrypt(int key, char *str): 解密学⽣成绩并返回 加密规则:把所有学⽣的成绩拼接成⼀个只包含数字的字符串,然后依据整数key对其进⾏加密。例如:数 字1被key=5加密之后变成6;数字5被key=5加密之后变成0。单个数字加密之后仍是单个数字。 解密规则与加密规则对称。
4. 数据分析 根据GPA对学⽣成绩进⾏考情分析:A+多少⼈,A多少⼈,以此类推。GPA等级参考SZTU评分等级。
5. ⽤户界⾯ 实现⼀个菜单,以供⽤户决定要使⽤哪个功能。
菜单参考:
Hello, pls input a series of student information!
(⽤户开始输入)
Okay, data upload finished. What do you what to do next? You can enter a number to tell me.
1 add
2 delete
3 search
4 sort by score
5 encrypt
6 decrypt
7 analysis
0 exit
(⽤户输入)
(输出计算结果)
Do you still need my service? You can enter a number to tell me.
1 add 2 delete 3 search 4 sort by score 5 encrypt 6 decrypt 7 analysis 0 exit
(⽤户输入) (输出计算结果)
代码:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_STUDENTS 100
#define ID_LENGTH 12
#define NAME_LENGTH 50
#define GPA_LENGTH 3
typedef struct {
char first_name[NAME_LENGTH];
char last_name[NAME_LENGTH];
char id[ID_LENGTH + 1];
int score;
char gpa[GPA_LENGTH];//GPA等级
char retake_info[4];//重修信息
int rank;//班级排名
} Student;
Student students[MAX_STUDENTS];//学生数组,用来存放每个学生的所有信息
int student_count = 0;//学生数量的全局变量
//计算学生GPA等级和重修信息的函数
void calculate_gpa_and_retake(Student* student) {
if (student->score >= 90)
{
strcpy(student->gpa, "A+");
}
else if (student->score >= 85)
{
strcpy(student->gpa, "A");
}
else if (student->score >= 80)
{
strcpy(student->gpa, "B+");
}
else if (student->score >= 75)
{
strcpy(student->gpa, "B");
}
else if (student->score >= 70)
{
strcpy(student->gpa, "C+");
}
else if (student->score >= 65)
{
strcpy(student->gpa, "C");
}
else if (student->score >= 60)
{
strcpy(student->gpa, "D");
}
else
{
strcpy(student->gpa, "F");
}
if (strncmp(student->id, "2022", 4) == 0) //判断是否为重修学生,如果是2022年就不是重修学生,其他才是重修学生
{
strcpy(student->retake_info, "No");
}
else
{
strcpy(student->retake_info, "Yes");
}
}
//添加学生信息的函数
void add_student(char* first_name, char* last_name, char* id, int score) {
if (student_count >= MAX_STUDENTS) {
printf("Cannot add more students.\n");
return;
}
strcpy(students[student_count].first_name, first_name);//添加第student_count+1个学生的名
strcpy(students[student_count].last_name, last_name); //添加第student_count+1个学生的姓
strcpy(students[student_count].id, id);//添加第student_count+1个学生的ID
students[student_count].score = score;//添加第student_count+1个学生的成绩
calculate_gpa_and_retake(&students[student_count]);//计算学生GPA值并添加,计算学生重修信息并添加
student_count++;//添加完学生数量加一
}
void delete_student(char* id) {
for (int i = 0; i < student_count; i++) {//遍历学生数组
if (strcmp(students[i].id, id) == 0) {//找出要删除的学生
//将后面的学生补上来
for (int j = i; j < student_count - 1; j++) {
students[j] = students[j + 1];
}
student_count--;//删除完学生的数量减1
printf("Student with ID %s deleted.\n", id);
return;
}
}
printf("Student with ID %s not found.\n", id);
}
void search_student(char* id) {
for (int i = 0; i < student_count; i++) {//遍历每个学生
if (strcmp(students[i].id, id) == 0) {
printf("Student found: %s %s, ID: %s, Score: %d, GPA: %s, Retake: %s\n",
students[i].first_name, students[i].last_name, students[i].id,
students[i].score, students[i].gpa, students[i].retake_info);
return;
}
}
printf("Student with ID %s not found.\n", id);
}
int compare_scores(const void* a, const void* b) {
return ((Student*)b)->score - ((Student*)a)->score;//比较学生的成绩,相等返回0,a大返回负数,b大返回正数
}
void sort_by_score() {
//按照我们自己定义的compare_scores规则来排序
qsort(students, student_count, sizeof(Student), compare_scores);
//排完序从第一名开始打印每一位学生信息
for (int i = 0; i < student_count; i++) {
printf("%s %s, ID: %s, Score: %d, GPA: %s, Retake: %s\n",
students[i].first_name, students[i].last_name, students[i].id,
students[i].score, students[i].gpa, students[i].retake_info);
}
}
char* encrypt(int key) {
//创建一个数组用来存放加密后学生的成绩,static保证这个函数用完数组不销毁
static char encrypted[ID_LENGTH * MAX_STUDENTS + 1];
encrypted[0] = '\0';//初始化这个数组为空数组
for (int i = 0; i < student_count; i++) {//遍历每个学生
char temp[5];//创建一个临时变量用来存储当前学生的成绩
sprintf(temp, "%d", students[i].score);//将当前学生的成绩转换成字符串
strcat(encrypted, temp);//将当前学生成绩追加到encrypted后面
}
//对 encrypted 数组中的每个字符进行加密。首先,将字符转换为数字(encrypted[i] - '0'),
// 然后加上密钥 key,对10取模(保证结果在0-9之间),最后再将数字转换回字符(+ '0')
for (int i = 0; i < strlen(encrypted); i++) {
encrypted[i] = ((encrypted[i] - '0' + key) % 10) + '0';
}
return encrypted;
}
char* decrypt(int key, char* str) {
//创建一个数组用来存放解密后学生的成绩,static保证这个函数用完数组不销毁
static char decrypted[ID_LENGTH * MAX_STUDENTS + 1];
strcpy(decrypted, str);//初始化 解密数组 为 加密数组
for (int i = 0; i < strlen(decrypted); i++) {
decrypted[i] = ((decrypted[i] - '0' - key + 10) % 10) + '0';
}
return decrypted;
}
void analyze_gpa() {
int count_a_plus = 0, count_a = 0, count_b_plus = 0, count_b = 0;
int count_c_plus = 0, count_c = 0, count_d = 0, count_f = 0;
//用计数器的方法计算每一个等级里的学生的人数
for (int i = 0; i < student_count; i++) {
if (strcmp(students[i].gpa, "A+") == 0) count_a_plus++;
else if (strcmp(students[i].gpa, "A") == 0) count_a++;
else if (strcmp(students[i].gpa, "B+") == 0) count_b_plus++;
else if (strcmp(students[i].gpa, "B") == 0) count_b++;
else if (strcmp(students[i].gpa, "C+") == 0) count_c_plus++;
else if (strcmp(students[i].gpa, "C") == 0) count_c++;
else if (strcmp(students[i].gpa, "D") == 0) count_d++;
else if (strcmp(students[i].gpa, "F") == 0) count_f++;
}
//将分析结果打印出来
printf("GPA Analysis:\n");
printf("A+ : %d\n", count_a_plus);
printf("A : %d\n", count_a);
printf("B+ : %d\n", count_b_plus);
printf("B : %d\n", count_b);
printf("C+ : %d\n", count_c_plus);
printf("C : %d\n", count_c);
printf("D : %d\n", count_d);
printf("F : %d\n", count_f);
}
int main() {
int choice;//选择变量
char first_name[NAME_LENGTH], last_name[NAME_LENGTH], id[ID_LENGTH + 1];//定义姓名变量,id变量
int score, key;//定义分数,解密变量
char encrypted[ID_LENGTH * MAX_STUDENTS + 1];//加密程序返回结果
printf("Hello, please input a series of student information!\n");//开始页面
do {
printf("What do you want to do next? You can enter a number to tell me.\n");
printf("1 add\n2 delete\n3 search\n4 sort by score\n5 encrypt\n6 decrypt\n7 analysis\n0 exit\n");
scanf("%d", &choice);//输入选择
switch (choice) {
case 1://添加学生
printf("Enter first name, last name, ID, and score:\n");
scanf("%s %s %s %d", first_name, last_name, id, &score);//输入姓名,id,成绩
add_student(first_name, last_name, id, score);//添加学生信息
break;
case 2://删除学生
printf("Enter ID to delete:\n");
scanf("%s", id);
delete_student(id);//删除ID对应学生的信息
break;
case 3://查找学生
printf("Enter ID to search:\n");
scanf("%s", id);
search_student(id);//查找并打印学生的信息
break;
case 4://给学生按照成绩来排序
sort_by_score();
break;
case 5://加密学⽣成绩
printf("Enter key for encryption:\n");
scanf("%d", &key);
printf("Encrypted scores: %s\n", encrypt(key));
break;
case 6://解密学生成绩
printf("Enter key for decryption and encrypted string:\n");
scanf("%d %s", &key, encrypted);
printf("Decrypted scores: %s\n", decrypt(key, encrypted));
break;
case 7://分析数据
analyze_gpa();
break;
case 0:
printf("Goodbye!\n");
exit(0);
default:
printf("Invalid choice. Please try again.\n");
}
} while (choice!=0);
return 0;
}
/*
学校:深圳技术大学
学生:23电科一班林耿超
注:程序仅供供参考,不可照搬照抄,转载请附上版权申明
*/