#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>
#include<time.h>
#include<Windows.h>
#include"studentmanagement.h"//这个是用vs2022 的头文件
//以下为头文件的内容:
#pragma once
#define Number1 3//这个是指代学生数
#define Number2 3//这个指代课程数
#define Number3 10//这个指代题目数
typedef struct student
{
char name[20];
long long int num;
int stuclass;
double scores[Number2];
double levels[Number2];
double average_levels;//这个只用于功能8.
}xs;
xs it[Number1]={0};
typedef struct course
{
char name[20]; // 课程名称
int num;//课程编号
int arr[Number3];//这个数组储存每道题的分数 完成相应试题所获取的分值,假设每门课程最多包括1000道试题
}kc;
kc ce[Number2]={0};
//函数内容其实也可以放在头文件中
//1.录入学生信息
void student_information();
//2.录入课程信息
void student_course();
//3.录入每道题的打分标准和相应分值。
void marking_standard();
//4.更新积分
void Updat_points();
//5.计算学生等级
void Calculate_rank();
//6.查找功能:查找指定学生的各门课程的积分和等级情况
void Find_Function();
//7.排序功能:将学生信息按某门课程的积分自高到低进行排序
void Sort_function();
//8.输出功能:将学生信息按照平均等级格式化输出。
void Output_function();
//9.删除某门课程的某个试题:主要用于更新需要删除过时或不合适的关卡。
void Delete_functionalit
//以下为源文件:
//1.
void student_information()
{
/*xs* it= (xs*)malloc(sizeof(xs) * Number1);*///不要将结构体储存在堆空间中因为这是一个大项目数据应该共用所以应该定义全局结构体数组
int i = 0;
FILE* fp1 = fopen("J:/学生信息.txt", "w");
if (!fp1)
{
printf("打开文件失败");
exit(0);
}
//给学生积分和等级赋初值
for (int i = 0; i < Number1; i++)
{
for (int j = 0; j < Number2; j++)
{
it[i].scores[j] = 0;
it[i].levels[j] = 0;
}
}
printf("请输入学生姓名和学号以及班级号(以:\n");
for (int i = 0; i < Number1; i++)
{
scanf("%s%lld%d", it[i].name, &it[i].num, &it[i].stuclass);
fprintf(fp1, "%s\t%lld\t%d\n", it[i].name, it[i].num, it[i].stuclass);
for (int j = 0; j < Number2; j++)
fprintf(fp1, " %0.0lf\n", it[i].scores[j]);
for (int j = 0; j < Number2; j++)
fprintf(fp1, " %0.0lf\n", it[i].levels[j]);
}
//while (i<Number1)
//{
//scanf("%s%d%d", it[i].name,&it[i].num,&it[i].stuclass);
//fputs(it[i].name, fp1);
//fputs("\t", fp1);
//fprintf(fp1, "%d\t%d", it[i].num,it[i].stuclass);
//fputs("\n", fp1);
//fprintf(fp1, "%0.0f\t%0.0f\t%0.0f\t%0.0f\t%0.0f\t%0.0f\t", it[i].scores[0], it[i].scores[1], it[i].scores[2], it[i].levels[0], it[i].levels[1], it[i].levels[2]);
//fputs("\n", fp1);
///*it[i].scores[0] = 0;
//it[i].scores[1] = 0;
//it[i].scores[2] = 0;
//it[i].levels[0] = 0;
//it[i].levels[1] = 0;
//it[i].levels[2] = 0;*/
// i++;
//}
fclose(fp1);
}
//2.
void student_course()
{
//kc* ce = (kc*)malloc(sizeof(kc) * Number2);没有用,同上理
FILE* fp2 = fopen("J:/课程信息.txt", "w");
if (!fp2)
{
printf("打开文件失败");
exit(0);
}
printf("请输入课程名称和课程编号:\n");
for (int i = 0; i <Number2; i++)
{
scanf("%s%d", ce[i].name,&ce[i].num );
fprintf(fp2, "%s\t%d\n", ce[i].name,ce[i].num);
}
fclose(fp2);
}
//3.
void marking_standard()
{//先假设每门课有十道题
//kc* p = (kc*)malloc(sizeof(kc) * Number2);没有用,同上理
FILE* fp3 = fopen("J:/每道题目的打分标准和相应分值.txt", "w");
printf("请输入每道题的相应分值:\n");
fputs("评分标准:对一道题就加上该题目相应的分数\n", fp3);
for (int i = 0; i < Number2; i++)
{
printf("第%d个科目的:\n",i+1);
fputs("该科目的每一道题目对应的分值:\n", fp3);
for (int j = 0; j < Number3; j++)
{
printf("第%d题的分数为:\n", j+1);
scanf("%d", &ce[i].arr[j]);
fprintf(fp3, "%d", ce[i].arr[j]);
fputs("\n", fp3);
}
}
fclose(fp3);
}
//4.
void Updat_points()
{//完成哪道题就加上哪道题的分数
int key = 0;
int arr[Number2][Number3] = { 0 };
int i = 0;
int j = 0;
FILE* fp4 = fopen("J:/每道题目的打分标准和相应分值.txt", "r");
FILE* fp1 = fopen("J:/学生积分信息.txt", "w");
//利用文件的随机读写把文件中数据读取出来
fseek(fp4, 40, SEEK_SET);
for (int i = 0; i < Number2; i++)
{
fseek(fp4, 31, SEEK_CUR);//为什么多了1,因为的最后的一个分值后面的\n也要算上
for (int j = 0; j < Number3; j++)
{
fscanf(fp4, "%d", &arr[i][j]);
}
}
printf("请输入该名学生相应课程答对的题目序号(注意每门课程的一道题只能输入一次):\n");
printf("若要换下一位同学请按'11',换下一个科目请输入12,若要结束输入请输入13:\n");
i = 0, j = 0;
while(key!=13)
{
scanf("%d", &key);
switch (key)
{
case 1:it[i].scores[j] += arr[j][0]; break;
case 2:it[i].scores[j] += arr[j][1]; break;
case 3:it[i].scores[j] += arr[j][2]; break;
case 4:it[i].scores[j] += arr[j][3]; break;
case 5:it[i].scores[j] += arr[j][4]; break;
case 6:it[i].scores[j] += arr[j][5]; break;
case 7:it[i].scores[j] += arr[j][6]; break;
case 8:it[i].scores[j] += arr[j][7]; break;
case 9:it[i].scores[j] += arr[j][8]; break;
case 10:it[i].scores[j] += arr[j][9]; break;
case 11:i++; j = 0; break;
case 12:j++;break;
case 13:break;//没有它每次结束程序都会输出一次下面的东西
default:printf("输入数据错误\n");
}
}
//直接将分数信息储存一个新文件中方便调用
for (int i = 0; i < Number1; i++)
{
for (int j = 0; j < Number2; j++)
{
fprintf(fp1,"%0.0lf\n", it[i].scores[j]);
}
}
//1.验证程序用的
//for (int i = 0; i < Number1; i++)
//{
//for (int j = 0; j < Number2; j++)
//{
//printf("%0.0f\n",it[i].scores[j]);
//}
//}
//2.验证程序用的
//printf("%d\n", i);
//printf("%d\n", j);
//for (int i = 0; i < Number1; i++)
//{
//for (int j = 0; j <Number2; j++)
//{
//printf("%d\n", it[i].scores[j]);
//}
//}
fclose(fp1);
fclose(fp4);
}
//5.
void Calculate_rank()
{
FILE* fp5 = fopen("J:/学生等级信息.txt", "w");
FILE* fp6 = fopen("J:/学生积分信息.txt", "r");
for (int i = 0; i < Number1; i++)
{
for (int j = 0; j < Number2; j++)
{
fscanf(fp6, "%lf\n", &it[i].scores[j]);
}
}
//调试用的程序
//for (int i = 0; i < Number1; i++)
//{
//for (int j = 0; j < Number2; j++)
//{
//printf("%0.0lf\n", it[i].scores[j]);
//}
//}
for (int i = 0; i < Number1; i++)
{
for (int j = 0; j < Number2; j++)
{
it[i].levels[j] = floor(log10(it[i].scores[j] + 1));//这个floor函数以及功能笔记本上有
}
}
//注意计算公式为log(),比如积分为0的等级为0;积分为1~98的等级为1;积分为99~998的等级为2;积分为999~9998的等级为3;……
for (int i = 0; i < Number1; i++)
{
for (int j = 0; j < Number2; j++)
{
fprintf(fp5, "%0.0f\n", it[i].levels[j]);
}
}
fclose(fp5);
fclose(fp6);
//log10 可以转到定义查看 而florr函数则可以看笔记本额外记录部分第6页
//验证程序用的
//for (int i = 0; i < Number1; i++)
//{
//for (int j = 0; j < Number2; j++)
//{
//printf("%0.0f\n", it[i].levels[j]);
//}
//}
//验证程序用的
//for (int i = 0; i < Number1; i++)
//{
//for (int j = 0; j < Number2; j++)
//{
//printf("%d\n", it[i].scores[j]);
//}
//}
}
//6.
void Find_Function()
{
//可以直接从上一个函数开始文件存读操作但没有必要
//查找功能:核心就是就是字符串比较 并且在这里同时完成了导入功能
char arr[20] = {0};
FILE* fp5 = fopen("J:/学生信息.txt", "r");
FILE* fp6 = fopen("J:/学生等级信息.txt", "r");
FILE* fp7 = fopen("J:/学生积分信息.txt", "r");
for (int i = 0; i < Number1; i++)
{
for (int j = 0; j < Number2; j++)
{
fscanf(fp6, "%lf", &it[i].levels[j]);
fscanf(fp7, "%lf", &it[i].scores[j]);
}
}
//for (int i = 0; i < Number1; i++)
//{
//for (int j = 0; j < Number2; j++)
//{
//printf("%0.0lf\n", it[i].levels[j]);
//printf("%0.0lf\n", it[i].scores[j]);
//}
//}
fseek(fp5, 0, SEEK_SET);
for (int i = 0; i < Number1; i++)
{
fscanf(fp5, "%s", it[i].name);
fseek(fp5,30, SEEK_CUR);//注意一位数和二位数
}
//验证程序用的
//for (int i = 0; i < Number1; i++)
//{
//printf("%s\n", it[i].name);
//}
printf("请输入想要查寻的学生:\n");
scanf("%s",arr);
for (int i = 0; i <=Number1; i++)
{
for (int j = 0; j < Number2; j++)
{
if (!strcmp(arr, it[i].name))//注意strcmp和strncmp的参数都应该为指针类型it[i].name就相当于一个地址
{
printf("%s同学的第%d门课的:\n等级:%0.0lf\n积分:%0.0lf\n", it[i].name, j + 1, it[i].levels[j], it[i].scores[j]);
}
else
{
printf("未查询到该同学\n");
return;
}
}
}
fclose(fp5);
fclose(fp6);
fclose(fp7);
}
//7.
void Sort_function()
{
//先从文件中提取出结构体的相应信息再排序,为什么这样干? 为了模块化实现相应功能
struct student temp;
FILE* fp8 = fopen("J:/学生积分信息.txt", "r");
FILE* fp9 = fopen("J:/学生等级信息.txt", "r");
FILE* fp10 = fopen("J:/学生信息.txt", "r");
FILE* fp11 = fopen("J:/学生信息排序后.txt", "w");
for (int i = 0; i < Number1; i++)
{
for (int j = 0; j < Number2; j++)
{
fscanf(fp8, "%lf",&it[i].scores[j]);
}
}
for (int i = 0; i < Number1; i++)
{
for (int j = 0; j < Number2; j++)
{
fscanf(fp9, "%lf\n",&it[i].levels[j]);
}
}
for (int k = 0; k < Number1; k++)
{
fscanf(fp10, "%s\t%lld\t%d", it[k].name, &it[k].num, &it[k].stuclass);
fseek(fp10,26, SEEK_CUR);//不明白为什么是26
}
//验证程序用的
//for (int i = 0; i < Number1; i++)
//{
//printf("%s\t%lld\t%d\n", it[i].name,it[i].num,it[i].stuclass);
//}
int i=0, j=0, k=0, t=0,e=0;
printf("请输入想要比较的科目的课程编号:\n");
scanf("%d", &e);
for ( i = 0; i <Number1-1 ; i++)
{
k = i;
for ( j = i+1; j <Number1 ; j++)
{
if (it[j].scores[e] > it[k].scores[e])
{
temp = it[i];
it[i] = it[k];
it[k] = temp;
}
}
}
for (int i = 0; i < Number1; i++)
{
fprintf(fp11, "%s\t%lld\t%d\n", it[i].name, it[i].num, it[i].stuclass);
for (int j = 0; j < Number2; j++)
fprintf(fp11, " %0.0lf\n", it[i].scores[j]);
for (int j = 0; j < Number2; j++)
fprintf(fp11, " %0.0lf\n", it[i].levels[j]);
}
fclose(fp8);
fclose(fp9);
fclose(fp10);
fclose(fp11);
}
//8.
void Output_function()
{
struct student temp;
FILE* fp8 = fopen("J:/学生积分信息.txt", "r");
FILE* fp9 = fopen("J:/学生等级信息.txt", "r");
FILE* fp10 = fopen("J:/学生信息.txt", "r");
for (int i = 0; i < Number1; i++)
{
for (int j = 0; j < Number2; j++)
{
fscanf(fp8, "%lf", &it[i].scores[j]);
}
}
for (int i = 0; i < Number1; i++)
{
for (int j = 0; j < Number2; j++)
{
fscanf(fp9, "%lf\n", &it[i].levels[j]);
}
}
for (int k = 0; k < Number1; k++)
{
fscanf(fp10, "%s\t%lld\t%d", it[k].name, &it[k].num, &it[k].stuclass);
fseek(fp10, 26, SEEK_CUR);//不明白为什么是26
}
//验证程序用的
//for (int i = 0; i < Number1; i++)
//{
//printf("%s\t%d\t%d\n", it[i].name, it[i].num, it[i].stuclass);
//}
int i=0, j=0, k=0, t=0;
double lzd=0;
for (int i = 0; i < Number1; i++)
{
it[i].average_levels = 0;
}
for (int i = 0; i < Number1; i++)
{
for (int j = 0; j < Number2; j++)
{
lzd += it[i].levels[j];
}
it[i].average_levels = lzd / 3;
}
for (i = 0; i < Number1 - 1; i++)
{
k = i;
for (j = i + 1; j < Number1; j++)
{
if (it[j].average_levels > it[k].average_levels)
{
temp = it[i];
it[i] = it[k];
it[k] = temp;
}
}
}
for (int i = 0; i < Number1; i++)
{
printf("%s\t%lld\t%d\n", it[i].name, it[i].num, it[i].stuclass);
for (int j = 0; j < Number2; j++)
printf(" %0.0lf\n", it[i].scores[j]);
for (int j = 0; j < Number2; j++)
printf(" %0.0lf\n", it[i].levels[j]);
}
fclose(fp8);
fclose(fp9);
fclose(fp10);
}
//9.
void Delete_functionality()
{
//把想删除哪道题就把哪道题的分值归零
int arr[Number2][Number3] = { 0 };
int i ;
int j ;
FILE* fp12 = fopen("J:/每道题目的打分标准和相应分值.txt", "r");
fseek(fp12, 40, SEEK_SET);
for (int i = 0; i < Number2; i++)
{
fseek(fp12, 31, SEEK_CUR);//为什么多了1,因为的最后的一个分值后面的\n也要算上
for (int j = 0; j < Number3; j++)
{
fscanf(fp12, "%d", &arr[i][j]);
}
}
//为什么把这个文件操作放在这里.因为:(上面是读取文件内容的操作)这里操作的是同一个文件,操作方式"w"会清空源文件,导致上述读取文件操作失败,从而导致arr[i][j]中全变为0,所以把这个文件操作放在后面.
FILE* fp13 = fopen("J:/每道题目的打分标准和相应分值.txt", "w");
printf("请输入想要更改的:\n第几门科目:\n第几道题:\n");
scanf("%d%d", &i, &j);
i -= 1; j -= 1;
arr[i][j]=0;
fputs("评分标准:对一道题就加上该题目相应的分数\n", fp13);
for (int i = 0; i < Number2; i++)
{
fputs("该科目的每一道题目对应的分值:\n", fp13);
for (int j = 0; j < Number3; j++)
{
fprintf(fp13, "%d", arr[i][j]);
fputs("\n", fp13);
}
}
fclose(fp12);
fclose(fp13);
}
//保存功能和导入功能在上面函数中均实现了
int main(void)
{
int key = 0;
while (key != 10)
{
system("cls");
system("mode con cols=120");
printf("\t\t\t\t---------------------------------------------------------\n");
//color(6);
printf("\t\t\t\t*\t \t欢迎使用药品信息管理系统 \t\t*\n");
//color(7);
printf("\t\t\t\t---------------------------------------------------------\n");
printf("\t\t\t\t*********************************************************\n");
printf("\t\t\t\t*\t*\t1.录入学生信息\t\t\t*\t*\n");
printf("\t\t\t\t*\t*\t2.录入课程信息\t\t\t*\t*\n");
printf("\t\t\t\t*\t*\t3.录入每道题的相应分值\t\t*\t*\n");
printf("\t\t\t\t*\t*\t4.(统计)更新积分 \t\t*\t*\n");
printf("\t\t\t\t*\t*\t5.计算学生等级\t\t\t*\t*\n");
printf("\t\t\t\t*\t*\t6.查找功能\t\t\t*\t*\n");
printf("\t\t\t\t*\t*\t7.排序功能\t\t\t*\t*\n");
printf("\t\t\t\t*\t*\t8.输出功能\t\t\t*\t*\n");
printf("\t\t\t\t*\t*\t9.删除某门课程的某个试题\t*\t*\n");
printf("\t\t\t\t*\t*\t10.退出系统\t\t\t*\t*\n");
printf("\t\t\t\t*********************************************************\n");
printf(" 请选择您的选择: ");
scanf("%d", &key);
switch (key)
{
case 1:student_information(); system("cls"); break;
case 2:student_course(); Sleep(10000); system("cls"); break;
case 3:marking_standard(); system("cls"); break;
case 4:Updat_points(); system("cls"); break;
case 5:Calculate_rank(); system("cls"); break;
case 6:Find_Function();Sleep(30000);system("cls"); break;
case 7:Sort_function(); system("cls"); break;
case 8: Output_function();Sleep(20000);system("cls"); break;//注意在windows中Sleep()函数是大写的:"S"这里Sleep(10000)是为了让输出内容浮现一会儿,而Sleep()中的数字大小控制浮现的时间
case 9: Delete_functionality(); system("cls"); return 0;
case 10:break;
default:printf("输入数据错误\n"); break;
}
}
return 0;
}