简单学生成绩管理系统

来源:互联网 发布:贵州云计算上市公司 编辑:程序博客网 时间:2024/04/28 21:00

/*
2016-5-16 11:20
fengh Z

反思: 
还有许多缺陷,比如:未对错误输入进行处理(1提示输入错误 2提供重新输入的机会) 
学生的学号使用char数组进行存储有点浪费内存空间
排序函数需要优化,函数中存在一些不必要的判断 
需要一个与文件通信的功能,见文件版 

总结:
对于指针,链表的运用依旧不熟悉,出 bug不知道哪的问题(比如越界访问),调试很重要 
 
*/


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <windows.h>
#include <time.h>
#include <ctype.h>
#include <conio.h> 
#include <stdbool.h>
#define N 30 
#define TRUE 1
#define FALSE 0


/*定义结构体*/
typedef struct student{
char name[N];
char id[N];
float grade_M;
float grade_E;
float grade_C;
float grade_sum;
}Item;


typedef struct node{
Item stu;
struct node * pnext;
}Node;


typedef Node* List;


int times=0; //用于统计getGrade函数使用的次数  


/*function*/
void welcome1(void); //开始界面 
int welcome(void); //功能选择界面 
int getGrade(List *);//成绩录入 
void printGrade(List *);//打印成绩 
int deleteGrade(List *);//成绩删除
int delete2(List *);
void changeGrade(List *);//成绩修改
void freeAllGrade(List *);//清除所有数据 
void quit(List *); 
void findGrade(List *);//查找成绩 
void sortGrade(List *, int);//成绩排序 ,按学号
void swap(Item * a, Item * b);
int addStuGrade(List *);//学生信息的添加 
void testKeyIsRight(void);//测试输入的密码是否正确 
int returnAnyTime(void);//随时返回函数 


/*主函数*/
int main(void)
{
List root=NULL;  //指向第一个节点的指针,注意:需要初始化为NULL指针 
int returnValue;
int num;

// system("color 0a"); //改变字体颜色 
welcome1();//开始界面 

while(1){
returnValue=welcome();

switch(returnValue){
case 1: num=getGrade(&root); 
break;
case 2: num-=deleteGrade(&root); 
break;
case 3: changeGrade(&root);
break;
case 4: findGrade(&root);
break;
case 5: sortGrade(&root, num);
break;
case 6: printGrade(&root);
break;
case 7: num+=addStuGrade(&root);
break;
case 8: quit(&root);
break;
default:printf("\n\n      -您的输入是未定义的!");
}
}


return 0;



int returnAnyTime(void)
{
char surekey;

while(getchar()!='\n')
;
printf("\n\n\n      是否确定使用这个功能? (Y/N) : ");
scanf("%c", &surekey);
if(toupper(surekey)=='Y')//需要一个返回到功能选择页面的语句,用goto吗? goto用不了 23333原因是goto用于同一个函数中 
return TRUE;
else
return FALSE;
}


int getGrade(List * phead)
{
Node * current;
Node * prev;
Item student;
int i=0;
int num;

system("cls");
if(!returnAnyTime()) //用户可再次判断是否使用该功能 
return 0;

if(times>0)  //需要一个函数用于清除原先存储的数据,用于不涉及文件操作的情况下 
freeAllGrade(phead);

printf("\n      您选择了录入功能,请输入学生的人数:");
scanf("%d", &num); 
printf("\n 请输入学生姓名,学号,数学成绩,英语成绩,语文成绩 :\n\n ");

while(i<num){


current=(Node *)malloc(sizeof(Node));
if(current==NULL){
fprintf(stderr, "内存分配失败!即将回到功能选择页面\n");
break;
}

if(5==scanf("%s %s %f %f %f", student.name, student.id, &student.grade_M, 
&student.grade_E, &student.grade_C)){
student.grade_sum=student.grade_M+student.grade_E+student.grade_C;
current->stu=student;
printf(" 录入成功!\n");
}

current->pnext=NULL;
if(*phead==NULL)
*phead=current;
else
prev->pnext=current;
prev=current;


printf(" ");
i++;
}
times++;
printf("\n\n\n      按下任意键返回..");
getchar();
getchar();

return num;
}


void freeAllGrade(List * phead)
{
Node * scan=*phead;
Node * prev;

while(scan!=NULL){
prev=scan;
scan=scan->pnext;
free(prev);
}
*phead=NULL;
// printf(" (已将原有数据清除!)\n");
}


int deleteGrade(List * phead)  
{
int select;
char ch='Y';
int i;

system("cls");
if(!returnAnyTime()) //用户可再次判断是否使用该功能 
return 0;
printf("\n\n\n      您选择了删除功能\n");

while(toupper(ch)=='Y'){
i=delete2(phead);  //对链表进行修改 

printf("\n      您所选择的对象现已删除,是否继续(Y/N) : ");
printf("      ");
ch=getchar();
while(getchar()!='\n')
;
}
printf("\n\n\n      按下任意键返回..");
getchar();

return i;
}


int delete2(List * phead) 
{
char stu_name[N];
Node * scan=*phead;
Node * prev=NULL;
int i=0;

printf("\n      输入要删除的学生的姓名 :");
scanf("%s", stu_name);
while(getchar()!='\n')
;

while(scan!=NULL){
if(0==strcmp(stu_name, scan->stu.name)){  //找到匹配的对象 
//进行指针的变动 
if(prev==NULL){  
prev=scan->pnext;
*phead=prev;
}
else
prev->pnext=scan->pnext;
i++;

break;
}
prev=scan;
scan=scan->pnext;
}
if(scan!=NULL)  //释放内存 
free(scan);


return i; //删除的人数 
}


void changeGrade(List * phead)  
{
Node * scan=*phead;
int select;
char stu_name[N];

system("cls");
if(!returnAnyTime()) //用户可再次判断是否使用该功能 
return ;
printf("\n\n\n      您选择了修改成绩功能\n\n");
printf("      输入要修改成绩的学生的姓名 :");
scanf("%s", stu_name);


while(scan!=NULL){
if(0==strcmp(stu_name, scan->stu.name)){
printf("\n      可进行修改的选项为 : 1.学号  2.数学成绩  3.英语成绩  4.语文成绩\n\n");
printf(" 您的选择是 : ");
scanf("%d", &select);

switch(select){
case 1: printf("\n      输入修改后的学号   : ");
scanf("%s", scan->stu.id);
break;
case 2: printf("\n      输入修改后的数学成绩 : ");
scanf("%f", &scan->stu.grade_M);
break;
case 3: printf("\n      输入修改后的英语成绩 : ");
scanf("%f", &scan->stu.grade_E);
break;
case 4: printf("\n      输入修改后的语文成绩 : ");
scanf("%f", &scan->stu.grade_C);
break;
}

while(getchar()!='\n')
;
printf("\n\n\n      修改完毕,按下任意键返回..");
getchar();
break;
}
else
scan=scan->pnext;
}
if(scan==NULL)
printf("      找不到您所要修改的对象!即将回到功能选择页面\n");
}


void findGrade(List * phead)
{
Node * scan=*phead;
char stu_name[N];

system("cls");
if(!returnAnyTime()) //用户可再次判断是否使用该功能 
return ;

printf("\n\n\n      您选择了查找个人成绩的功能\n\n");
printf("      输入该学生的姓名:");
scanf("%s", stu_name);

while(scan!=NULL){
if(0==strcmp(stu_name, scan->stu.name)){
printf("\n      该学生基本信息为 : 姓名   学号   数学成绩   英语成绩    语文成绩\n\n");  //贼丑 
printf("           %4s%8s%16.2f%16.2f%16.2f\n", scan->stu.name, scan->stu.id, 
scan->stu.grade_M, scan->stu.grade_E, scan->stu.grade_C, scan->stu.grade_sum);
break;
}
else
scan=scan->pnext;
}

printf("\n\n\n      按下任意键返回..");
getchar();
getchar();
}


void sortGrade(List * phead, int num) 
{
Node * head=*phead;
Node * current=*phead;
Node * next=current->pnext;
int i, j;

system("cls");
if(!returnAnyTime()) //用户可再次判断是否使用该功能 
return ;

printf("\n\n\n      您选择了按学号进行排序的功能\n\n");


for(i=0; i<num; i++){ //需要优化 
for(j=0; j<num-i-1; j++){
if(strcmp(current->stu.id, next->stu.id)>0) //大的排后面,在学号为相同长度的情况下是正确的
//如果出现学号为 2323 234 这种情况结果就会出错
//更好的方式是将表示学号的char数组转换为整数进行比较,然后再排序 
swap(&current->stu, &next->stu);
next=next->pnext;
current=current->pnext;
if(next==NULL)
break;
}
current=head; //回到头部 
next=current->pnext; 
}


printf("      排序已完成\n");
printf("\n\n\n      按下任意键返回..");
getchar();
getchar();
}


void swap(Item * a, Item * b)
{
Item temp;

temp=*a;
*a=*b;
*b=temp;
}


int addStuGrade(List * phead)
{
Node * scan=*phead;
Node * current=NULL;
Item stu;
int i=0;
int n;

system("cls");
if(!returnAnyTime()) //用户可再次判断是否使用该功能 
return 0;

while(scan->pnext!=NULL)
scan=scan->pnext;

printf("\n\n\n      您选择了追加成绩的功能\n\n");
printf("\n      输入要追加学生的个数 : ");
scanf("%d", &n);
printf("\n      输入该生的姓名, 学号, 数学成绩, 英语成绩, 语文成绩 :\n\n");

while(i<n){
current=(Node *)malloc(sizeof(Node));
if(current==NULL){
fprintf(stderr, "内存分配失败!即将回到功能选择页面\n");
break;
}

printf("      ");
if(5==scanf("%s %s %f %f %f", stu.name, stu.id, &stu.grade_M, 
&stu.grade_E, &stu.grade_C))
stu.grade_sum=stu.grade_M+stu.grade_E+stu.grade_C;

current->stu=stu;
current->pnext=NULL;
scan->pnext=current;
scan=current;

printf("\n      追加成功\n"); 
i++;
}
printf("\n      追加已完成!\n");
printf("\n\n\n      按下任意键返回..");
getchar();
getchar();

return n;
}


void printGrade(List * phead)  //贼丑 
{
Node * p=*phead;
system("cls");
if(!returnAnyTime()) //用户可再次判断是否使用该功能 
return ;

printf("\n\n\n      学生成绩打印如下:\n\n");
printf("      姓名\t学号\t\t数学成绩\t英语成绩\t语文成绩\n");
while(p!=NULL){
printf("\n\n      %4s%8s%16.2f%16.2f%16.2f\n", p->stu.name, p->stu.id, 
p->stu.grade_M, p->stu.grade_E, p->stu.grade_C, p->stu.grade_sum);
p=p->pnext;
}
printf("\n\n\n      按下任意键返回..");
getchar();
getchar();
}
 
/*开始界面*/
void welcome1(void)
{
time_t i;

time(&i);
system("cls");  //清屏 
printf("\n\n\n\n\n -*-*-*-*-*-*-*简版学生信息管理系统*-*-*-*-*-*-*-\n\n"); //gotoXY函数的使用
printf("     time : %s\n", asctime(localtime(&i)));
printf("         author:%s\n\n", "fengh Z");
printf("\n\n\n     输入管理员密码:");

testKeyIsRight();



void testKeyIsRight(void)
{
int j=1; //用于统计输入密码的次数,三次输入错误则结束程序
char key[N]; 

while(j<=3){
scanf("%s", key);

if(strcmp(key, "123456")!=0){
if(j==3){
printf("\n  您已使用完输入密码的次数,3秒后结束程序.. ");
for(; j>0; j--){
Sleep(1000);//延时函数:1000为1秒 
printf("%d\b", j);
}
exit(EXIT_FAILURE);
}
//怎么让这个提示只出现一次 
printf("\n\n        -密码错误,您还有%d次机会\n", 3-j); 
printf("        -再次输入 : ");
j++;
}
else{
printf("\n        -密码正确,即将进入功能界面..\n");
Sleep(1000);
break;
}
}
}


int welcome(void)
{
int select;

system("cls");
printf("\n\n\n -本系统所有功能选项如下根据情况进行选择-\n\n");
printf(" -1. 成绩录入 -2. 删除成绩\n\n");
printf(" -3. 更改成绩 -4. 成绩查询\n\n");
printf(" -5. 成绩排序 -6. 成绩打印\n\n");
printf(" -7. 追加成绩 -8. 退出程序\n\n");
printf("\n -您的选择是: ");
scanf("%d", &select);

return select; 
}


void quit(List * phead)
{
time_t t;

time(&t);
system("cls");
printf("\n\n\n\n\n\n\n\n     感谢使用本系统,再见!\n\n");
printf(" time : %s\n", asctime(localtime(&t)));
freeAllGrade(phead);//释放内存 
Sleep(2000);
exit(EXIT_SUCCESS);
}

0 0
原创粉丝点击