您的位置:首页 > 其它

C编写简单的学生成绩管理系统

2012-10-05 23:15 543 查看
学校的一个创新学分的课程题目是《学生成绩管理系统》,不涉及数据库操作,只需将数据输入存在文件中即可。编译器:VS2010,C编写。以后有时间再用C++写下。

实现的功能有:

1.账号和密码登录,直接用字符串比较函数即可实现,为了防止密码被人看见,用***代替了密码的显示(当然也可以用其它的来代替显示,比如不显示,linux终端下输入密码就是这样),具体实现见代码即可。

2.输入成绩。这里要分两种情况,手动输入和从文件(已存在的成绩文件)导入。手动输入简单,文件导入设计到一些文件的操作,自己编体会更深些。

3.显示全部成绩。这个直接讲结构体中的数据输出即可,注意输出的格式控制。

4.查询某个学生的成绩。通过关键字--学号,遍历找到,输出即可。

5.修改某个学生的成绩。同样是通过学号,找到该学生,这里假设名字和性别不会输错,只提供了修改成绩的功能。假设学号也可以输错,该通过什么来找到该学生,从而修改呢???

6.添加成绩。即插入操作,分插在最后和中间某个位置。插在中间某个位置,就是从最后的元素开始从后向前逐个向后移动即可。

7.删除某个学生的成绩。找到该学生后,将后面的学生逐个向前移动即可。

8.成绩统计。就是统计平均分的分段,并绘制条形图。以及每门课的平均分、最高分、最低分。 绘制条形图,用的是较老的TC下的画图工具(需要下载一个东西,百度下即可),貌似还可以用第三方的库,GDI,或者通过excel来画图,还没研究好。 程序中实现的画图,由于兼容性,没能在图中输入变量,标出每个分数段的百分比。。然后运行完画图程序后,cmd也会关闭,这个还没来得及解决,一般运行,都将这步放到最后。


9.保存成绩。将数据写到文件中,txt文档注意用的是fprintf函数。

10.退出系统。

主函数的框架,就是一个循环和switch分支语句。 运行结果比较长,就不贴了,程序是可以运行的过的。下面贴下代码吧:

// C语言创新学分_成绩管理.cpp : 定义控制台应用程序的入口点。

#include "stdafx.h"
#include <windows.h>			//必须调用此函数,才能避免winnt.h的编译错误
#include <winnt.h>
#include <graphics.h>			//调用TC中的画图函数,VS2010需要下载相应的这个
#include<string.h>
#include<stdlib.h>
#include<conio.h>

#define NumOfCourse 3   //3门课
#define N 40		//最多存储40个人

struct student {
	char name[8];		//姓名
	char num[6];			//学号,字符数组
	char sex[2];		//性别,M代表男,W代表女
	char chinese[8];	//课程1
	char english[8];	//课程2
	char math[8];		//课程3
	float score[NumOfCourse];   //3门课成绩
	float sum;   //总分
	float mean;		//平均分
};

int number;			//全局变量,学生人数和学生的结构信息
student stu
;

//函数声明
int log_in(void);			//登陆输入账号、密码设置  账号为zy,密码为123,使用***代替密码
void menu(void);			//欢迎菜单界面   0
void inputscore(void);			//输入学生学号分数信息或者从文件中导入数据,更方便   1
void lookscore(void);			//查看学生的成绩信息   2
void searchscore(void);			//查询某个学生的成绩情况,根据学号来查    3
void modifyscore(void);				//修改某个学生的成绩,根据学号找到学生,重新输入成绩   4
void addscore(void);			//添加成绩  5
void deletescore(void);			//删除成绩  6
void sortscore(void);			//成绩排序   7
void statiscore(void);			//统计数据,统计平均分的分布情况,以及每门课的平均分、最低分、最高分,条形图   8
void savescore(void);			//保存成绩,保存到txt文档中去          9
int quit(void);					//退出系统与否 10

int main(int argc, _TCHAR* argv[])
{
	int choose;    //操作选择,学生人数
	int log_in_flag,quit_flag;		//登录成功与否标志和退出系统的标志
	log_in_flag = log_in();
	if (log_in_flag == 1) {
		return 1;
	}

	menu();				//显示欢迎菜单
	scanf("%d", &choose);
	while(1) {
		switch(choose)
		{
			case 0: menu();       break;
			case 1: inputscore(); break;
			case 2: lookscore();  break;
			case 3: searchscore();break;
			case 4: modifyscore();break;
			case 5: addscore();   break;
			case 6: deletescore();break;
			case 7: sortscore();  break;
			case 8: statiscore(); break;
			case 9: savescore();  break;
			case 10: quit_flag = quit(); if(quit_flag == 0) exit(0); else break;
			default: exit(0); break;
		}
		printf("请输入你的选择:   ");
		scanf("%d", &choose);
	}
	return 0;
}

int log_in(void)
{
	char ID[6];
	char PASSWORD[11];
	int count = 0;
	while(1) {
		int i=0;
		printf("请输入用户名:  ");
		scanf("%s",ID);
		printf("请输入密码(密码长度小于10位):   ");
		while( i<10 && ((PASSWORD[i]=getch()) != '\r') ) {		//设计实现用*号代替密码,防止窃取密码,当然也可以什么都不输出
			if( PASSWORD[i] != '\b'){
				printf("*");
				i++;
			}
			else {			// \b是删除键对应的字符
				printf("\b");   //回到前一列
				printf(" ");	//在当前位置上输出空格,此时,光标已经到下一列位置了
				printf("\b");	//再回到前一列位置上,以便输入
				i--;
			}

 		}
		PASSWORD[i] = '\0';
		printf("\n");

		if( (strcmp(ID,"zy") == 0) && (strcmp(PASSWORD,"123") == 0) ) {
			printf("账号和密码正确\n");
			return 0;
		}
		else {
			printf("账号或者密码不正确,请核对后重新输入!!!你只有三次机会\n");
			count +=1;
			if(count == 3) {
				printf("3次机会已用完,怀疑你不能操作该成绩!\n");
				return 1;
			}
		}
	}
}

void menu(void)
{
	printf("**********欢迎来到学生成绩管理系统********************\n");
	printf("                   菜单                             \n");
	printf("命令菜单-------------------------------------------0\n");
	printf("输入成绩-------------------------------------------1\n");
	printf("查看全部成绩---------------------------------------2\n");
	printf("查询某个成绩---------------------------------------3\n");
	printf("修改成绩-------------------------------------------4\n");
	printf("添加成绩-------------------------------------------5\n");
	printf("删除成绩-------------------------------------------6\n");
	printf("成绩排序-------------------------------------------7\n");
	printf("成绩统计-------------------------------------------8\n");		//待完成
	printf("保存成绩-------------------------------------------9\n");
	printf("退出系统------------------------------------------10\n");
	printf("****************************************************\n");
	printf("请输入你的选择:  ");
}

void inputscore(void)
{
	int i=0;
	int choose =0;
	printf("手动输入成绩请按'1',从文件中导入成绩请按'2'\n");
	scanf("%d",&choose);
	if( 1 == choose) {
		printf("请输入学生人数:   \n");
		scanf("%d", &number);
		printf("注意学号的位数要小于6位,处于排版考虑,最好是3位数字,例如:001  \n");
		for( ; i < number ; i++) {
			printf("请输入第 %d 个学生的姓名、学号和性别:  \n",i+1);
			scanf("%s%s%s", stu[i].name,stu[i].num,stu[i].sex);
			printf("\n请输入第 %d 个学生的成绩: \n",i+1);
			printf("语文 英语 数学\n");
			int j=0;
			for( ;j<NumOfCourse; j++) {
				scanf("%f",&(stu[i].score[j]));
				stu[i].sum += stu[i].score[j];		//同学i的总分
			}
			stu[i].mean = stu[i].sum/NumOfCourse;    //同学i的平均分
			printf("\n");
		}
	}

	else if( 2 == choose) {
		FILE *fp;
		char ch=1;
		int count=1;		//最后一行没有换行符,直接是结束符了
		fp = fopen("E:\\score.txt", "rt");
		if( fp == NULL) {
			printf("cannot open this file!\n");
			exit(0);
		}
		ch = fgetc(fp);
		while(ch != '\n') {			//读取第一行
			ch = fgetc(fp);
		}
		for( int j=0;ch != EOF; i++) {
			fscanf(fp, "%s%s%s%f%f%f%f%f",stu[i].name,stu[i].num,stu[i].sex,&stu[i].score[0],&stu[i].score[1],&stu[i].score[2],&stu[i].sum,&stu[i].mean);

			ch = fgetc(fp);
			if(ch == '\n') {
				count += 1;
			}
			if(ch == EOF) {
				break;
			}
		}
		number = count;
		printf("从文件中导入成绩成功!\n");
		fclose(fp);
	}
}

void lookscore()
{
	int i=0;
	printf("姓名  学号   性别   语文   英语   数学   总分   平均分\n");
	for( ; i< number; i++) {
		printf("%-4s%6s%7s",stu[i].name,stu[i].num,stu[i].sex);   //姓名,学号
		for( int j=0; j<NumOfCourse; j++) {
			printf("%7.2f", stu[i].score[j] );
		}
		printf("%7.2f%9.2f",stu[i].sum,stu[i].mean);
		printf("\n");
	}
}

void searchscore()
{
	int i=0;
	printf("请输入要查找学生的学号:   ");		//输入学号
	char no[6];
	scanf("%s", no);
	for( ; i< N; i++) {
		if( strcmp(no,stu[i].num) == 0 ) {
			printf("姓名  学号   性别   语文   英语   数学   总分   平均分\n");
			printf("%-4s%6s%7s",stu[i].name,stu[i].num,stu[i].sex);
			for( int j=0; j<NumOfCourse; j++) {
				printf("%7.2f", stu[i].score[j] );
			}
			printf("%7.2f%9.2f",stu[i].sum, stu[i].mean);
			printf("\n");
			break;
		}
	}
	if(i == N) {
		printf("输入的学号 %s 有误,请核对后再尝试查找!\n ",no);
	}
}

void modifyscore(void)
{
	char no[6];
	printf("请输入你想修改成绩的学生的学号:   ");		//学号比姓名更能标志一个人的信息
	scanf("%s",no);
	int i = 0;
	for( ; i<number; i++) {
		if( strcmp( no, stu[i].num ) == 0 ) {
			printf("语文 英语 数学\n");
			scanf("%f%f%f",&stu[i].score[0],&stu[i].score[1],&stu[i].score[2]);
			stu[i].sum = stu[i].score[0] + stu[i].score[1] + stu[i].score[2];
			stu[i].mean = stu[i].sum/NumOfCourse;
			printf("成功修改学号为 %s 的成绩 ,如果想保存到记事本中,请注意在主菜单中按保存按钮!\n",no);
			break;
		}
	}
	if(i == number) {
		printf("输入的学号不存在,想修改的话,请从新操作!\n");
	}
}

void addscore(void)
{
	int insertnumber;
	student insert;
	int i;
	char m;

	printf("请输入想插入的学生的信息:\n");
	printf("姓名 学号 性别\n");
	scanf("%s%s%s",insert.name,insert.num,insert.sex);
	printf("语文 英语 数学\n");
	scanf("%f%f%f",&insert.score[0], &insert.score[1], &insert.score[2]);
	insert.sum = insert.score[0] +insert.score[1] +insert.score[1];
	insert.mean = insert.sum /NumOfCourse;
	printf("是否插入到最后(Y/N):   ");
	fflush(stdin);
	scanf("%c",&m);
	if( m == 'y' || m == 'Y' )  {
		stu[number] = insert;
		printf("成功插入到末尾!\n");
		number += 1;
	}
	else if(  m == 'n' || m == 'N')   {

		printf("请输入插入的位置,现在共有 %d 个学生\n", number);
		scanf("%d",&insertnumber);
		if( insertnumber<0 || insertnumber >= number) {
			printf("插入的位置不对!\n");
			return;
		}
		for( i = number; i >= insertnumber ; i--) {
			stu[i] = stu[i-1];
		}
		stu[i] = insert;
		number += 1;
		printf("插入成功!\n");
	}
	else {
		printf("请输入正确的选择!\n");
		return ;
	}
}

void deletescore(void)
{
	int deletenumber;
	char no[6];
	printf("请输入要删除学生的学号:  ");
	scanf("%s",no);
	int i;
	for( i=0; i<number; i++) {
		if( strcmp(no, stu[i].num) == 0)  {
			deletenumber = i;
			printf("该学号位于第 %d 个位置\n",i+1);
			break;
		}

	}
	if( i == number) {
		printf("成绩表中没有这个学号存在,请核对后再次输入!\n");
		return;
	}

	for(  i= deletenumber; i<number-1; i++) {
		stu[i] = stu[i+1];
	}
	number -= 1;
	printf("成功删除学号为 %s 的学生.\n",no);
}

void sortscore(void)
{
	int i=0,j=0;
	student temp;
	int flag = 0;
	for( ;i < number; i++) {			//冒泡法进行排序
		flag = 1;
		for( j = 0 ;j < number - i-1; j++) {
			if( stu[j].mean < stu[j+1].mean ) {
				temp = stu[j];
				stu[j] = stu[j+1];
				stu[j+1] = temp;
				flag =0;
			}
		}
		if( 1 == flag) {
			break;
		}
	}
	printf("已成功排序\n");

}

void statiscore(void)
{
	int i = 0;
	float chinese_sum = 0, english_sum = 0, math_sum = 0;
	float chinese_mean=0, english_mean =0, math_mean = 0;
	int chinese_high = stu[0].score[0];
	int chinese_low = stu[0].score[0];		//语文成绩的最高分和最低分
	int english_high = stu[0].score[1];
	int english_low = stu[0].score[1];		//英语成绩的最高分和最低分
	int math_high = stu[0].score[2];
	int math_low = stu[0].score[2];			//数学成绩的最高分和最低分
	int count1 = 0,count2 = 0,count3 = 0;
	for( ; i< number; i++) {
		//平均分统计
		if( stu[i].mean <60 ) {
			count1 += 1;
		}
		else if( stu[i].mean >= 60 && stu[i].mean <= 80 ) {
			count2 += 1;
		}
		else count3 += 1;

		//3门课各自的平均分和最高分、最低分统计
		chinese_sum += stu[i].score[0];  english_sum += stu[i].score[1]; math_sum += stu[i].score[2];

		if( chinese_high < stu[i].score[0] ) chinese_high = stu[i].score[0];
		if( chinese_low > stu[i].score[0] ) chinese_low = stu[i].score[0];

		if( english_high < stu[i].score[1] ) english_high = stu[i].score[1];
		if( english_low > stu[i].score[1] ) english_low = stu[i].score[1];

		if( math_high < stu[i].score[2] ) math_high = stu[i].score[2];
		if( math_low > stu[i].score[2] ) math_low = stu[i].score[2];

	}
	chinese_mean = chinese_sum/number;  english_mean = english_sum/number; math_mean = math_sum/number;
	float f1,f2,f3;
	f1 = float(count1)/number; f2 = float(count2)/number; f3 = float(count3)/number;
	printf("该班 %d 个人中平均分低于60分的人数有 %d 人,占了%.2f\n", number,count1,f1);
	printf("该班 %d 个人中平均分大于60小于80分的人数有 %d 人,占了%.2f \n", number,count2,f2);
	printf("该班 %d 个人中平均分高于80分的人数有 %d 人,占了%.2f\n", number,count3,f3);

	printf("该班 %d 个人中语文成绩平均分是%.2f ,最高分是 %d ,最低分是 %d\n",number,chinese_mean,chinese_high,chinese_low);
	printf("该班 %d 个人中英语成绩平均分是%.2f ,最高分是 %d ,最低分是 %d\n",number,english_mean,english_high,english_low);
	printf("该班 %d 个人中数学成绩平均分是%.2f ,最高分是 %d ,最低分是 %d\n",number,math_mean,math_high, math_low);
//绘制平均分的条形图
	int gdriver=DETECT,gmode;			//左上角是原点
    initgraph(&gdriver,&gmode,"E:\\Code");
    setcolor(WHITE);		//设置前背景颜色,白色
     //坐标轴,y
    line(100,50,100,400);
    line(90,60,100,50);
    line(110,60,100,50);	
    //x
    line(100,400,550,400);
    line(540,390,550,400);
    line(540,410,550,400);

	outtextxy(100,30,_T('y') );
	outtextxy(560,400,_T('x') );
	outtextxy(500,50,_T("学生平均分条形图") );
    //第一个条子
    setfillstyle(1,BLUE); //第一个参数范围为0-11(0为背景色填充,12为自定义)
    bar(150,(400-350*f1),170,400);
	outtextxy(150,410,_T("<60") );		//字符编码的问题

    //第二个条子
    setfillstyle(2,RED);
    bar(250,(400-350*f2),270,400);
	outtextxy(250,410,_T("60-80") );

    //第三个条子
    setfillstyle(3,YELLOW);
    bar(350,(400-350*f3),370,400);
	outtextxy(350,410,_T(">80") );

	saveimage(_T("E:\\test.bmp") );			//保存图像
    getch();
    closegraph();
}

void savescore(void)
{
	FILE *fp;
	char m;
	int i;
	printf("是否保存成绩(y/n):");
	fflush(stdin);			//scanf输入字符时会读取回车键,需要清空,或者在%c前加一个空格
	scanf("%c",&m);
	if( m == 'y' || m == 'Y' ) {
		fp = fopen("E:\\score.txt", "wt");			//保存的文件目录 C:\Users\zy-pc\Desktop\score.txt
		if( fp == NULL) {
			printf("cannot open file\n");
			return;
		}
		fprintf(fp,"姓名  学号   性别   语文   英语   数学   总分   平均分\n");
		for( i = 0; i<number; i++) {
			fprintf(fp,"%-4s%6s%7s%7.2f%7.2f%7.2f%7.2f%9.2f\n", stu[i].name, stu[i].num,stu[i].sex,stu[i].score[0],stu[i].score[1],stu[i].score[2],stu[i].sum,stu[i].mean);
		}
		printf("成绩保存成功!\n");
		fclose(fp);
	}
	else if( m == 'n' || m == 'N')
		printf("没有保存成绩!\n");
	else  {
		printf("请输入Y/N 或者 y/n,成绩没有保存成功 \n");
		return;
	}
}

int quit(void)
{
	char m;
	printf("是否确定退出系统,请先想想成绩是否已经保存到文件中! (y/n)" );
	fflush(stdin);			//scanf输入字符时会读取回车键,需要清空,或者在%c前加一个空格
	scanf("%c",&m);
	if( m == 'y' || m == 'Y' )  {
		printf("确认退出系统!\n");
		return 0;   //返回0,是确定退出系统
	}
	else if( m == 'n' || m == 'N')   {
		printf("取消退出系统!\n");
		return 1;		//返回1,取消退出系统
	}
	else { printf("无效输入,当做不退出系统考虑\n"); return 1;}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: