c语言课设之学生成绩管理系统
提示:大一第一次写课设,刚开始特别紧张,感觉无从下手,也是看了很多学长们的博客才慢慢理解如何去做,这篇博客既是对自己的总结,也希望能够帮到有需要的人。
void f1(int n);
void f2(int n);
void xmcx(int n);
void xhcx(int n);
void f3(int n);
void f4(int n);
void f5(int n);
void f6(int n);
void dkzs(int n);
void pjfzs(int n);
void f7(int n);
/*用于从存储学生信息的文件中读取信息,写入信息等操作*/
struct student {
char xh[10];
char name[20];
int banji = 0;
int kemu[3];
};
/*用于平均分,姓名,学号的写入与后续读出*/
struct average {
char sxh[10];
char sname[20];
float pingjunfen;
};
/*用于登录和注册*/
struct yonghumima {
char yonghuming[20];
char password[20];
};
#include
#include
#include
#include"main.h"
int main()
{
int slabel = 1;
int n = 60;/*总人数,用于函数传递很方便*/
while (slabel==1) {
int c;
/*登录和注册界面*/
printf("-----欢迎使用博客作业登录系统-----\n");
printf("|--1:用户登录: |\n");
printf("|--2:用户注册: |\n");
printf("|--0:退出: |\n");
printf("------------------------------\n");
scanf("%d", &c);
/*选择登录、注册或退出*/
switch (c) {
case 1: {
int label = -1;
int h, i;
struct yonghumima shi;
struct yonghumima shuru;
/*打开已经设定好的用户名和密码文件,用于后面的登录*/
FILE* fp;
if ((fp = fopen("C:\\mima.txt", "r")) == NULL)
{
printf("File open error!\n");
exit(0);
}
fscanf(fp, "%s%s", &shi.yonghuming, &shi.password);
fclose(fp);
printf("请输入用户名和密码(用空格隔开):\n");
/*这个循环是设定可尝试的次数并进行相应提醒*/
for (i = 0; i < 5; i++)
{
scanf("%s %s", &shuru.yonghuming, &shuru.password);
if (strcmp(shi.yonghuming, shuru.yonghuming) == 0 && strcmp(shi.password, shuru.password) == 0)
{
printf("登录成功!!!\n");
slabel = -1;
label = 1;
break;
}
if (i < 4)
{
printf("请重新输入用户名和密码(剩余%d次机会):\n", 4 - i);
}
if (i == 4)
printf("输入错误的次数太多,需要重新注册账号和密码!!!\n");
}
/*使用while而不使用if是因为while又构成了一个循环,后面switch(h)时的break就不会相当于退出系统即输入零的效果*/
while (label == 1)
{
printf("-------欢迎进入博客作业统计系统-------\n");
printf("|-1:返回菜单: |\n");
printf("|-2:展示班级作业情况: |\n");
printf("|-3:展示个人成绩: |\n");
printf("|-4:修改成绩: |\n");
printf("|-5:删除信息: |\n");
printf("|-6:统计平均分并写入文件: |\n");
printf("|-7:展示分数小于60分同学信息: |\n");
printf("|-8:完成数据统计: |\n");
printf("|-0:退出系统: |\n");
printf("--------------------------------------\n");
scanf("%d", &h);
if (h == 0) {
printf("感谢使用博客统计系统!!!\n");
break;
}
switch (h)
{
case 1: break;
case 2:f1(n); break;
case 3:f2(n); break;
case 4:f3(n); break;
case 5:f4(n); break;
case 6:f5(n); break;
case 7:f6(n); break;
case 8:f7(n); break;
}
}
break;/*这个break主要用于退出系统时在跳出case 1的循环*/
if (label != 1)
{
slabel = -1;
break;
}/*用于用户名和密码5次输入错误后关闭系统*/
}; break;
case 2: {
int m;
printf("----1:注册:\n");
printf("----0:退出:\n");
scanf("%d", &m);
switch (m)
{
case 1: {
FILE* fp;
struct yonghumima zhuce;
if ((fp = fopen("C:\\mima.txt", "w")) == NULL)
{
printf("File open error!\n");
exit(0);
}
printf("请输入您想使用的用户名和密码:(用空格隔开):\n");
scanf("%s %s", &zhuce.yonghuming, &zhuce.password);
rewind(fp);
fprintf(fp, "%s %s", zhuce.yonghuming, zhuce.password);
fclose(fp);
printf("注册成功,即将进入初始界面,可使用您注册的账号密码登录!!!\n");
}; break;
case 0:break;
default:printf("输入错误!!!\n"); break;
}
}; break;
case 0: {
slabel = -1;
printf("感谢使用博客统计系统!!!\n");
break;
}
default:printf("输入错误!!!\n"); break;
}
}
}
我设计的主函数有两个主要的模块,包括登录注册模块和成绩管理模块。最主要的操作是对于文件的读取和写入,最重要的结构是利用多层switch结构和设立标签。登录就是打开读入已经存储的账号密码文件数据,然后将其与输入的账号密码比较,相同则进入第二模块,并且利用for循环设立只有5次输入账号密码的机会。注册模块则是用读写打开文件,将输入的账号密码写入文件,及注册成功。第二模块就是利用switch选择调用不同的函数来解决问题。
#include
#include
#include
#include"main.h"
void f1(int n)
{
struct student stu[60];
int sbanji;
int skemu;
int i, a, label = -1;
FILE* fp;
if ((fp = fopen("C:\\chengji.txt", "r")) == NULL)
{
printf("File open error!\n");
exit(0);
}
for (i = 0; i < n; i++)
{
fscanf(fp, "%s%s%d%d%d%d", &stu[i].xh, &stu[i].name, &stu[i].banji, &stu[i].kemu[0], &stu[i].kemu[1], &stu[i].kemu[2]);
}
printf("----1:展示:\n");
printf("----0:退出:\n");
scanf("%d", &a);
switch (a)
{
case 1: {
printf("请输入班级:(1,2班)\n");
scanf("%d", &sbanji);
printf("请输入作业科目:(分为1,2,3共3科)\n");
scanf("%d", &skemu);
for (i = 0; i < n; i++)
{
if (stu[i].banji == sbanji && skemu <= 3 && skemu >= 1) {
label = i;
}
}
if (label == -1)
printf("输入的班级或科目有误!!!\n");
else
{
for (i = 0; i < n; i++)
printf("%d\n", stu[i].kemu[skemu - 1]);
}
}
case 0:break;
default:printf("输入错误!!!\n"); break;
}
}
利用标签确定输入的数据是否合理,利用if判断是否进行后续操作还是利用break退出循环。
#include
#include
#include
#include"main.h"
void f2(int n) {
int k;
printf("----请选择查询类型:\n");
printf("----1:按姓名查询:\n");
printf("----2:按学号查询:\n");
printf("----0:退出:\n");
scanf("%d", &k);
switch (k)
{
case 1:xmcx(n); break;
case 2:xhcx(n); break;
case 0:break;
default:printf("输入错误!!!\n"); break;
}
}
void xhcx(int n)
{
struct student stu[60];
char num[10];
int i, a, label = -1;
FILE* fp;
if ((fp = fopen("C:\\chengji.txt", "r")) == NULL)
{
printf("File open error!\n");
exit(0);
}
for (i = 0; i < n; i++)
{
fscanf(fp, "%s%s%d%d%d%d", &stu[i].xh, &stu[i].name, &stu[i].banji, &stu[i].kemu[0], &stu[i].kemu[1], &stu[i].kemu[2]);
}
printf("----1:查询:\n");
printf("----0:退出:\n");
scanf("%d", &a);
switch (a)
{
case 1: {
printf("请输入学号:\n");
scanf("%s", &num);
for (i = 0; i < n; i++)
{
if (strcmp(num, stu[i].xh) == 0) {
label = i;
break;
}
}
if (label == -1)
printf("输入的学号无对应的学生信息\n");
else
printf("%s %s %d %d %d %d\n", stu[label].xh, stu[label].name, stu[label].banji, stu[label].kemu[0], stu[label].kemu[1], stu[label].kemu[2]);
}; break;
case 0:break;
default:printf("输入错误!!!\n"); break;
}
if (fclose(fp)) {
printf("Can not close the file!\n");
exit(0);
}
}
void xmcx(int n)
{
struct student stu[60];
char sname[20];
int i, a, label = -1;
FILE* fp;
if ((fp = fopen("C:\\chengji.txt", "r")) == NULL)
{
printf("File open error!\n");
exit(0);
}
for (i = 0; i < n; i++)
{
fscanf(fp, "%s%s%d%d%d%d", &stu[i].xh, &stu[i].name, &stu[i].banji, &stu[i].kemu[0], &stu[i].kemu[1], &stu[i].kemu[2]);
}
printf("----1:查询:\n");
printf("----0:退出:\n");
scanf("%d", &a);
switch (a)
{
case 1: {
printf("请输入姓名:\n");
scanf("%s", &sname);
for (i = 0; i < n; i++)
{
if (strcmp(sname, stu[i].name) == 0) {
label = i;
break;
}
}
if (label == -1)
printf("输入的学号无对应的学生信息\n");
else
printf("%s %s %d %d %d %d\n", stu[label].xh, stu[label].name, stu[label].banji, stu[label].kemu[0], stu[label].kemu[1], stu[label].kemu[2]);
}
case 0:break;
default:printf("输入错误!!!\n"); break;
}
if (fclose(fp)) {
printf("Can not close the file!\n");
exit(0);
}
}
此文件包含三个函数:
1、利用switch结构进入选择查找方式界面。
2、打开存储学生信息的文件,利用结构体数组,将输入的学号与读入的学号比较,若合理则展示对应学号的数据,否则输出该学号无对应的信息。
3、打开存储学生信息的文件,利用结构体数组,将输入的姓名与读入的姓名比较,若合理则展示对应学号的数据,否则输出该学号无对应的信息。
#include
#include
#include
#include"main.h"
void f3(int n)
{
struct student stu[60];
char sxh[10];
int i, a;
int num = -1;
FILE* fp;
if ((fp = fopen("C:\\chengji.txt", "r+")) == NULL)
{
printf("File open error!\n");
exit(0);
}
for (i = 0; i < n; i++)
{
fscanf(fp, "%s%s%d%d%d%d", &stu[i].xh, &stu[i].name, &stu[i].banji, &stu[i].kemu[0], &stu[i].kemu[1], &stu[i].kemu[2]);
}
printf("----1:修改:\n");
printf("----0:退出:\n");
scanf("%d", &a);
switch (a)
{
case 1: {
printf("请输入要修改学生的学号:\n");
scanf("%s", &sxh);
struct student std;
for (i = 0; i < n; i++)
{
if (strcmp(sxh, stu[i].xh) == 0) {
num = i;
break;
}
}
if (num == -1)
printf("输入的学号无对应的学生信息\n");
else
{
printf("修改的信息学号,姓名,班级,科目一,科目二,科目三分别为:(用空格隔开)\n");
scanf("%s %s %d %d %d %d", &std.xh, &std.name, &std.banji, &std.kemu[0], &std.kemu[1], &std.kemu[2]);
strcpy(stu[i].xh, std.xh);
strcpy(stu[i].name, std.name);
stu[i].banji = std.banji;
stu[i].kemu[0] = std.kemu[0];
stu[i].kemu[1] = std.kemu[1];
stu[i].kemu[2] = std.kemu[2];
rewind(fp);
for (i = 0; i < n; i++)
{
fprintf(fp, "%s %s %d %d %d %d\n", stu[i].xh, stu[i].name, stu[i].banji, stu[i].kemu[0], stu[i].kemu[1], stu[i].kemu[2]);
}
if ((strcmp(std.xh, stu[num].xh) == 0) && (std.kemu[1] == stu[num].kemu[1]))
printf("修改成功!!!\n");
}
}; break;
case 0:break;
default:printf("输入错误!!!\n"); break;
}
fclose(fp);
}
打开存储学生信息的文件,利用结构体数组,将要修改信息的学号输入并与读入的学号对比,若存在则可输入要修改的信息进行修改,否则输出该学号无对应的信息。
#include
#include
#include
#include"main.h"
void f4(int n)
{
char xh1[10];
struct student stu[60];
struct student std[60];
int i, a;
int num = -1;
FILE* fp;
if ((fp = fopen("C:\\chengji.txt", "r+")) == NULL)
{
printf("File open error!\n");
exit(0);
}
for (i = 0; i < n; i++)
{
fscanf(fp, "%s%s%d%d%d%d", &stu[i].xh, &stu[i].name, &stu[i].banji, &stu[i].kemu[0], &stu[i].kemu[1], &stu[i].kemu[2]);
}
printf("----1:删除:\n");
printf("----0:退出:\n");
scanf("%d", &a);
switch (a)
{
case 1: {
printf("请输入要删除学生的学号:\n");
scanf("%s", xh1);
for (i = 0; i < n; i++)
{
if (strcmp(xh1, stu[i].xh) == 0)
{
num = i;
break;
}
}
if (num == -1)
printf("输入的学号无对应的学生信息\n");
else
{
for (i = 0; i < n - 1; i++)
{
if (i < num)
std[i] = stu[i];
else
std[i] = stu[i + 1];
}
rewind(fp);
for (i = 0; i < n - 1; i++)
{
fprintf(fp, "%s %s %d %d %d %d\n", std[i].xh, std[i].name, std[i].banji, std[i].kemu[0], std[i].kemu[1], std[i].kemu[2]);
}
printf("删除成功!!!\n");
}
}; break;
case 0:break;
default:printf("输入错误!!!\n"); break;
}
fclose(fp);
}
打开存储学生信息的文件,利用结构体数组,将要修改信息的学号输入并与读入的学号对比,若存在则可输入要修改的信息进行修改,否则输出该学号无对应的信息。
#include
#include
#include
#include"main.h"
void f5(int n)
{
struct student stu[60];
int i, a;
float pingjunfen[60];
printf("----1:计算并储存:\n");
printf("----0:退出:\n");
scanf("%d", &a);
switch (a)
{
case 1: {
FILE* fp;
FILE* fpw;
if ((fp = fopen("C:\\chengji.txt", "r")) == NULL)
{
printf("File open error!\n");
exit(0);
}
for (i = 0; i < n; i++)
{
fscanf(fp, "%s%s%d%d%d%d", &stu[i].xh, &stu[i].name, &stu[i].banji, &stu[i].kemu[0], &stu[i].kemu[1], &stu[i].kemu[2]);
}
for (i = 0; i < n; i++)
{
pingjunfen[i] = (stu[i].kemu[0] + stu[i].kemu[1] + stu[i].kemu[2]) * 1.0 / 3;
}
if ((fpw = fopen("C:\\average.txt", "r+")) == NULL)
{
printf("File open error!\n");
exit(0);
}
for (i = 0; i < n; i++)
{
fprintf(fpw, "%s %s %.2f\n", stu[i].xh, stu[i].name, pingjunfen[i]);
}
fclose(fp);
fclose(fpw);
printf("计算并保存成功!!!\n");
}; break;
case 0:break;
default:printf("输入错误!!!\n"); break;
}
}
打开存储学生信息的文件,利用结构体数组,计算出平均分,然后再打开要写入的文件,将相应信息写入。
#include
#include
#include
#include"main.h"
void f6(int n)
{
int i, num;
printf("----请选择根据单科成绩或平均分展示信息\n");
printf("----1:单科成绩展示\n");
printf("----2:根据平均分展示\n");
printf("----0:退出\n");
scanf("%d", &num);
switch (num)
{
case 1:dkzs(n); break;
case 2:pjfzs(n); break;
case 0:break;
default:printf("输入错误!!!\n"); break;
}
}
void dkzs(int n)
{
struct student stu[60];
struct average std[60];
int i, a, b = 1;
int skemu;
printf("----1:展示:\n");
printf("----0:退出:\n");
scanf("%d", &a);
switch (a)
{
case 1: {
FILE* fp;
FILE* fpw;
if ((fp = fopen("C:\\chengji.txt", "r")) == NULL)
{
printf("File open error!\n");
exit(0);
}
for (i = 0; i < n; i++)
{
fscanf(fp, "%s%s%d%d%d%d", &stu[i].xh, &stu[i].name, &stu[i].banji, &stu[i].kemu[0], &stu[i].kemu[1], &stu[i].kemu[2]);
}
if ((fpw = fopen("C:\\average.txt", "r")) == NULL)
{
printf("File open error!\n");
exit(0);
}
for (i = 0; i < n; i++)
{
fscanf(fpw, "%s%s%f", &std[i].sxh, &std[i].sname, &std[i].pingjunfen);
}
printf("请输入根据哪一科展示(1,2,3共三科)\n");
scanf("%d", &skemu);
for (i = 0; i < n; i++)
{
if (skemu != 1 && skemu != 2 && skemu != 3)
{
printf("输入科目错误!\n");
b = 2;
break;
}
if (stu[i].kemu[skemu] < 60)
printf("%s %s %d %d %d %d %.2f\n", stu[i].xh, stu[i].name, stu[i].banji, stu[i].kemu[0], stu[i].kemu[1], stu[i].kemu[2], std[i].pingjunfen);
}
if (b == 1)
printf("展示成功!!!\n");
fclose(fp);
fclose(fpw);
}; break;
case 0:break;
default:printf("输入错误!!!\n"); break;
}
}
void pjfzs(int n)
{
int i, a;
struct average stu[60];
struct student std[60];
printf("----1:展示:\n");
printf("----0:退出:\n");
scanf("%d", &a);
switch (a)
{
case 1: {
FILE* fp;
FILE* fpw;
if ((fp = fopen("C:\\average.txt", "r")) == NULL)
{
printf("File open error!\n");
exit(0);
}
for (i = 0; i < n; i++)
{
fscanf(fp, "%s%s%f", &stu[i].sxh, &stu[i].sname, &stu[i].pingjunfen);
}
if ((fpw = fopen("C:\\chengji.txt", "r")) == NULL)
{
printf("File open error!\n");
exit(0);
}
for (i = 0; i < n; i++)
{
fscanf(fpw, "%s%s%d%d%d%d", &std[i].xh, &std[i].name, &std[i].banji, &std[i].kemu[0], &std[i].kemu[1], &std[i].kemu[2]);
}
for (i = 0; i < n; i++)
{
if (stu[i].pingjunfen < 60)
printf("%s %s %d %d %d %d %.2f\n", std[i].xh, std[i].name, std[i].banji, std[i].kemu[0], std[i].kemu[1], std[i].kemu[2], stu[i].pingjunfen);
}
printf("展示成功!!!\n");
fclose(fp);
fclose(fpw);
}; break;
case 0:break;
default:printf("输入错误!!!\n"); break;
}
}
1、利用switch进入选择以某种方式展示界面。
2、根据输入的科目,利用合适的结构体数组读出学生信息,若不及格,则输出其信息。
3、打开存储平均分和信息的文件,读入,若平均分小于60,则输出其信息。
#include
#include
#include
#include"main.h"
void f7(int n)
{
int a, i, j,c;
int count[3][10] = { 0 };
struct student stu[60];
printf("----1:打印:\n");
printf("----0:退出:\n");
scanf("%d", &c);
switch (c)
{
case 1: {
printf("请输入要打印并储存的科目(1,2,3共三门):\n");
scanf("%d", &a);
if (a == 1 || a == 2 || a == 3) {
FILE* fp;
if ((fp = fopen("C:\\chengji.txt", "r+")) == NULL)
{
printf("File open error!\n");
exit(0);
}
for (i = 0; i < n; i++)
{
fscanf(fp, "%s%s%d%d%d%d", &stu[i].xh, &stu[i].name, &stu[i].banji, &stu[i].kemu[0], &stu[i].kemu[1], &stu[i].kemu[2]);
}
for (i = 0; i < n; i++)
{
if (stu[i].kemu[a - 1] >= 0 && stu[i].kemu[a - 1] <= 9)
count[a - 1][0]++;
if (stu[i].kemu[a - 1] >= 10 && stu[i].kemu[a - 1] <= 19)
count[a - 1][1]++;
if (stu[i].kemu[a - 1] >= 20 && stu[i].kemu[a - 1] <= 29)
count[a - 1][2]++;
if (stu[i].kemu[a - 1] >= 30 && stu[i].kemu[a - 1] <= 39)
count[a - 1][3]++;
if (stu[i].kemu[a - 1] >= 40 && stu[i].kemu[a - 1] <= 49)
count[a - 1][4]++;
if (stu[i].kemu[a - 1] >= 50 && stu[i].kemu[a - 1] <= 59)
count[a - 1][5]++;
if (stu[i].kemu[a - 1] >= 60 && stu[i].kemu[a - 1] <= 69)
count[a - 1][6]++;
if (stu[i].kemu[a - 1] >= 70 && stu[i].kemu[a - 1] <= 79)
count[a - 1][7]++;
if (stu[i].kemu[a - 1] >= 80 && stu[i].kemu[a - 1] <= 89)
count[a - 1][8]++;
if (stu[i].kemu[a - 1] >= 90 && stu[i].kemu[a - 1] <= 100)
count[a - 1][9]++;
}
for (j = 0; j < 10; j++) {
for (i = 0; i < count[a - 1][j]; i++)
{
printf("* ");
}
if (j == 9)
printf("%d——%d 共%d个人\n", 10 * j, 10 * (j + 1), count[a - 1][j]);
else
printf("%d——%d 共%d个人\n", 10 * j, 10 * (j + 1) - 1, count[a - 1][j]);
}
}
else
printf("输入的科目信息有误!!!\n");
}; break;
case 0:break;
default:printf("输入错误!!!\n"); break;
}
}
根据选择的科目,利用多个if计算出每段的人数,利用循环输出对应个数的*号。