[学生成绩管理系统]c实现

#include<stdio.h>
#include<malloc.h>
#include<string.h>
#include<stdlib.h>
#include<windows.h>
#include<conio.h>
#include<time.h>
/*********************************宏定义*****************************************/
#define N 100                                //结构体中数组的大小
/*********************************函数声明***************************************/
void save_file();        
void Delay();                
/*********************************自定义数据类型*********************************/
typedef struct stu
{
        char num[N];                        //学号
        char name[N];                        //姓名
        char chinese[N];                //语文
        char math[N];                        //数学

        struct stu* pnext;

}STU;
/*********************************全局变量定义*********************************/
STU* pStu = NULL;                        //表头
STU* pCurrent = NULL;                //当前学生(已经存在)
STU* pNew=NULL;                                //当前学生(待输入)
char KEY[7];                                //服务密码
/*********************************子函数定义***********************************/
//登陆验证        
void InCheck()                                                        
{        
        int InputLimit= 0;
        char keynumber[7]="0";
        int i = 0;

        srand((unsigned)time(NULL));                //生成随机验证码
        for(i=0;i<6;i++)
        {
                KEY[i] = rand() % 10  + 48; 
        }
        KEY[6] = '\0';

        system("cls");
        system("color 3e");

        printf("\n\n\t┌================================================┑\n");
        printf("\n\n");
        printf("\t\t\t欢迎使用学生信息管理系统\n");
        printf("\t\t\t\t\n");
        printf("\t\t\t\t\n");
        printf("\t\t\t\t\n");
        printf("\t\t\t请输入验证码登陆此系统\n");
        printf("\t\t\t<验证码是%s>\n",KEY);
        printf("\t\t\t \n");
        printf("\t\t\t如果3次输入均不正确,将退出系统\n");

        printf("\n\n\t┕================================================┚\n");
        
        
        scanf("%s",keynumber);
        while(strcmp(keynumber,KEY)!=0)
        {        InputLimit++;
                if(InputLimit==3)
                {        printf("\t您输入错误的次数已经到达%d次,您将退出系统",InputLimit);
                        Delay();
                        exit(0);
                }
                printf("\n\t\t您的输入有误!请重新输入\n");
                scanf("%s",keynumber);
        }

        system("cls");
        
}
//检查信息合法性:输入的都是数字字符吗?
char InformationCheck(const char *str)                        
{
        int L = 0;
        int i = 0;
        int PointCount=0;
        int NumCount = 0;


        L = strlen(str);
        for(i=0;i<L;i++)
        {        if(str[i]=='.')
                        PointCount++;
                if((str[i]<'0'||str[i]>'9')&&str[i]!='.')
                {        printf("\t您输入不合法,请重新输入\n");
                        return 1;
                }

        }
        if(PointCount>1)
        {        printf("\t您输入不合法,请重新输入\n");
                return 1;
        }
        else
        {
                return 0;
        }
}
//输入的信息容错后期处理[在InformationCheck,确保没有重大错误之后]
void InformationDebug(char *str)        
{
        int L = 0;
        char PointFlag=0;
        int IntCount = 0;
        int FloatCount = 0;                        //小数部分
        int i = 0;        
        int PositionOfPoint = 0;        //小数点所在的下标
        int ZeroPre = 0;                        //无用的0的个数
        char NotZeroStartFlag=0;        //字符串中开始出现了第一个1-9的数字字符

        L= strlen(str);

        for(i=0;i<L;i++)
        {        if(str[i]>='1'&&str[i]<='9')
                        NotZeroStartFlag=1;

                if(str[i]=='.')
                {        
                        PointFlag = 1;
                        PositionOfPoint = i;
                }
                else if(!PointFlag)
                        IntCount++;
                else
                        FloatCount++;

                if((PointFlag==0)&&(NotZeroStartFlag==0)&&(str[i]=='0')&&(str[i+1]!='.'))        //多余的'0'
                        ZeroPre++;
        }

        if(IntCount==0)                                                                //没有整数部分?
        {
                for(i=L;i>0;i--)
                {
                        str[i]=str[i-1];
                }
                str[0] = '0';
                str[L+1] = '\0';
                PositionOfPoint++;
        }
        if(FloatCount==0&&PointFlag == 1)                        //有小数点却没有小数部分?
        {
                str[PositionOfPoint+1] = '0';
                str[PositionOfPoint+2] = '\0';
        }
        if(ZeroPre>0)
        {
                strcpy(str,str+ZeroPre);
        }
        if(!NotZeroStartFlag)                                                //字符串中从来没有出现过1 -9 字符
        {
                strcpy(str,"0");
        }
}
//检查信息合法性:有没有输入的学号已经存在?
char NumCheck(const char *str)                        
{
        STU * View = NULL;
        int L = 0;
        int i = 0;

        View = pStu->pnext;


        while(View!=NULL)
        {
                if(strcmp(str,View->num)==0)
                {        printf("\t您输入的学号已经存在,请重新输入\n");
                        return 1;
                }
                View=View->pnext;
        }
                                                                                //输入的学号是在0 -9 之内的字符吗
        L = strlen(str);
        for(i=0;i<L;i++)
        {        
                if(str[i]<'0'||str[i]>'9')
                {        printf("\t您输入的字符应在'0'-'9'之间输入,请重新输入\n");
                        return 1;
                }
        }

        return 0;


}
//信息数字检查,,只检查字符串里面是不是只有 '0' - '9' 字符
void NumberCheck(char *str,char *Display)
{
        while(NumCheck(str))
        {
                printf("\t%s:",Display);
                scanf("%s",str);

        }
}
//信息过安检,不仅仅检查字符串里面是不是有除了'0' - '9'和'.'以外的字符,还进行消除冗余的'0'的操作
void SecureCheck(char *str,char *DisPlay)
{
                while(InformationCheck(str))
        {
                
                printf("\t%s:",DisPlay);
                scanf("%s",str);
        }
        InformationDebug(str);
}
//增加学生信息
void AddInformation()                                                                
{        
        int placed=0;
        STU* vIew = NULL;

        system("cls");

        placed=0;
        pNew = (STU *)malloc(sizeof(STU));                        
        pNew->pnext = NULL;
        printf("\t请输入要增加的学生信息:\n");

        printf("\t学号:");
        scanf("%s",pNew->num);
        //信息检查
        NumberCheck(pNew->num,"学号");


        printf("\t姓名:");
        scanf("%s",pNew->name);
        
        
        printf("\t语文:");
        scanf("%s",pNew->chinese);
        //信息检查
        SecureCheck(pNew->chinese,"语文");

        printf("\t数学:");
        scanf("%s",pNew->math);
        //信息检查
        SecureCheck(pNew->math,"数学");
        //信息检查
        vIew = (STU *)malloc(sizeof(STU));
        
        if(pStu->pnext==NULL)
                pStu->pnext=pNew;
        else                                                                //查找最佳位置进行升序插入节点, 维护学号升序顺序的插入
        {        
                vIew->pnext=pStu;
                while(vIew->pnext->pnext!=NULL)
                {
                        if(strcmp(vIew->pnext->num , pNew->num)<=0 && strcmp(vIew->pnext->pnext->num ,pNew->num)>=0)
                        {        
                        
                                pNew->pnext = vIew->pnext->pnext;
                                vIew->pnext->pnext = pNew;
                                placed=1;                                //表示已经放置
                                break;
                                
                        }
                        vIew->pnext = vIew->pnext->pnext;
                }
                if(placed==0)
                        vIew->pnext->pnext = pNew;        //没有找到合适的节点,把pNew挂在链表最后面
                
        }
        
        free(vIew);
        vIew=NULL;
        
}
//显示信息
void ShowInformation()                                        
{
        STU* vIew = NULL;

        system("cls");
        printf("\n\t┍====================显示信息====================┑\n");
        
        
        vIew = (STU *)malloc(sizeof(STU));

        vIew->pnext=pStu->pnext;
        if(vIew->pnext==NULL)
        {
                printf("\n\t\t当前档案内没有学生信息");
        }
        else
        {
                while(vIew->pnext!=NULL)
                {
                printf("\t学号:%s\n",vIew->pnext->num);
                printf("\t姓名:%s\n",vIew->pnext->name);
                printf("\t语文:%s\n",vIew->pnext->chinese);
                printf("\t数学:%s\n",vIew->pnext->math);
                printf("\n\t...................................................\n");
                vIew->pnext=vIew->pnext->pnext;
                }
        }
        free(vIew);
        vIew=NULL;

        printf("\n\t┕====================显示信息完毕================┙\n");

}

//查找信息
void Search()                                                
{
        char serach[N];
        int flag=0;
        char choice='0';
        STU* vIew = NULL;

        system("cls");
                                                                        //选择查找的根据[学号/姓名]
        printf("\n\t输入指令\t 1、按照学号查找 \t2、按照姓名查找\n");
        choice = getch();

        if(choice=='1')
                printf("\t请输入要查找的学生的学号:\n");
        else if(choice=='2')
                printf("\t请输入要查找的学生的姓名:\n");
        else
                printf("\t您的指令输入有误!已经退出查找\n");

        if(choice=='1'||choice=='2')        //如果指令是正确的
        {
                scanf("%s",serach);

        
                vIew = (STU *)malloc(sizeof(STU));

                vIew->pnext=pStu->pnext;
                while(vIew->pnext!=NULL)
                {
                        if((strcmp(vIew->pnext->num,serach)==0&&choice == '1')||(strcmp(vIew->pnext->name,serach)==0&&choice == '2'))
                        {flag=1;
                        printf("\t学号:%s\n",vIew->pnext->num);
                        printf("\t姓名:%s\n",vIew->pnext->name);
                        printf("\t语文:%s\n",vIew->pnext->chinese);
                        printf("\t数学:%s\n",vIew->pnext->math);
                        printf("\n\t...................................................\n");
                        }
                vIew->pnext=vIew->pnext->pnext;
                }
                free(vIew);
                vIew=NULL;

                if(!flag)
                printf("\n!!!!!!!!!!!!!!!!!!!!对不起,查无此人!!!!!!!!!!!!!!!!!!!!!!!!!\n");
        }

}
//删除信息
void Delete()                                                        
{        
        STU *temp;
        char num_serach[N];
        int flag=0;
        STU* vIew = NULL;

        system("cls");

        temp=(STU *)malloc(sizeof(STU));
        
        
        printf("\n\t请输入要删除的学生的学号:\n");
        scanf("%s",num_serach);



        vIew = (STU *)malloc(sizeof(STU));
        
        vIew->pnext=pStu;
        while(vIew->pnext->pnext!=NULL)
        {
                if(strcmp(vIew->pnext->pnext->num,num_serach)==0)                //匹配到了学号
                {
                flag=1;
                printf("\n\n\t待删除的学生信息为:\n");
                printf("\t学号:%s\n",vIew->pnext->pnext->num);
                printf("\t姓名:%s\n",vIew->pnext->pnext->name);
                printf("\t语文:%s\n",vIew->pnext->pnext->chinese);
                printf("\t数学:%s\n",vIew->pnext->pnext->math);
                
                temp ->pnext=vIew->pnext->pnext;                                                //temp->next保存将要删除的节点的地址
                vIew->pnext->pnext=vIew->pnext->pnext->pnext;                        //绕过将要删除的节点

                free(temp->pnext);                                                                                //释放已经被绕过的节点,节省空间
                
                printf("\n\t待删除的学生已经删除\n");                        
                printf("\n\t...................................................\n");
                break;                                                                                                        //删除一个节点之后,跳出循环体
                }
                vIew->pnext=vIew->pnext->pnext;
        }

        free(vIew);
        vIew=NULL;
        free(temp);
        temp=NULL;

        if(!flag)
        printf("\n!!!!!!!!!!!!!!!!!!!!对不起,查无此人!!!!!!!!!!!!!!!!!!!!!!!!!\n");

}
//修改信息
void Modify()                                                                
{        
        char num_serach[N];
        int flag=0;
        STU* vIew = NULL;
        
        system("cls");
        
        printf("\n\t请输入要修改的学生的学号:\n");
        scanf("%s",num_serach);

        
        vIew = (STU *)malloc(sizeof(STU));

        vIew->pnext=pStu->pnext;
        while(vIew->pnext!=NULL)
        {
                if(strcmp(vIew->pnext->num,num_serach)==0)
                {
                        flag=1;
                printf("\t学号:%s\n",vIew->pnext->num);
                printf("\t姓名:%s\n",vIew->pnext->name);
                printf("\t语文:%s\n",vIew->pnext->chinese);
                printf("\t数学:%s\n",vIew->pnext->math);
                printf("\t修改成:\n");
                //新信息的输入
                printf("\t语文:\n");
                scanf("%s",vIew->pnext->chinese);
                //信息检查
                SecureCheck(vIew->pnext->chinese,"语文");

                //信息检查
                printf("\t数学:\n");
                scanf("%s",vIew->pnext->math);
                //信息检查
                SecureCheck(vIew->pnext->math,"数学");
                //信息检查
                
                //AddInformation();        //原则上不修改学号和姓名;但如果要;可以直接用AddInformation()函数
                                                        //去代替新信息的输入
                printf("\n\t...................................................\n");
                }
                vIew->pnext=vIew->pnext->pnext;
        }
        free(vIew);
        vIew=NULL;

        if(!flag)
        printf("\n!!!!!!!!!!!!!!!!!!!!对不起,查无此人!!!!!!!!!!!!!!!!!!!!!!!!!\n");
        
}
//数据统计
void Statistical()
{
        double score    = 0;
        int    Number   = 0;
        int    Over90   = 0;
        int    Below60  = 0;

        STU *View = NULL;
        View = pStu->pnext;
        
        system("cls");

        printf("\t进行数据统计:\n");
        while(View!=NULL)
        {        
                score += atof(View->math) + atof(View->chinese);
                if(atof(View->math)<60||atof(View->chinese)<60)
                {
                        Below60++;
                }
                if(atof(View->math)>=90&&atof(View->chinese)>=90)
                {
                        Over90++;
                }

                Number++;
                View = View->pnext;
        }
        printf("\n\t学生的总人数是:%d",Number);

        if(Number!=0)
                printf("\n\t学生的总平均分是:%.2f",score/Number);
        else
                printf("\n\t学生的总平均分是:0");

        printf("\n\t学生总分数是:%.2f",score);
        printf("\n\t存在不及格科目的学生的人数是:%d",Below60);
        printf("\n\t两科分数均达到90的学生人数是:%d",Over90);
}
//根据总成绩进行排序[改变指针指向的方法进行链表排序]
void Sort()                                                                                
{        
        STU *View_0 = NULL;
        STU *View_1 = NULL;
        STU *View_2 = NULL;
        int StudentNumber = 0;
        int i = 0,j = 0;
        float SortKey1 = 0,SortKey2=0,result=0;                                //排序因素
        char  Choice = 0;
        
        system("cls");
        printf("\n1.以学号为依据排序 2.以总分为依据排序: ");
        Choice = getch();
        printf("%c",Choice);

        while(Choice!='1'&&Choice!='2')
        {        printf("\n输入错误!重新输入  1.以学号为依据排序 2.以总分为依据排序: ");
                Choice = getch();
                printf("%c",Choice);
        }

        
        View_0 = pStu->pnext;
        while(View_0!=NULL)
        {
                View_0 = View_0 ->pnext;
                StudentNumber++;
        }
        printf("\n学生的个数为%d\n",StudentNumber);
        
        if(StudentNumber<2)
        {
                printf("\n表内学生数据少于2个,无需排序\n");//只有头结点或者除了头结点之外只有一个节点,不用排序
        }
        else
        {        
                
                //exchange A(View_1)and B(View_2)                                //冒泡排序
                for(i=0;i<StudentNumber-1;i++)
                {        
                        View_0 = pStu;
                        View_1 = pStu->pnext;
                        View_2 = View_1->pnext;

                        for(j=0;j<StudentNumber-1-i;j++)
                        {        
                                if(Choice=='2')                                                                                //排序因素:是拿什么来排序?
                                {        //学生的总成绩为排序因素
                                        SortKey1 = atof(View_1->math)+atof(View_1->chinese);
                                        SortKey2 = atof(View_2->math)+atof(View_2->chinese);
                                        result = (SortKey1)<(SortKey2)? 1:0;
                                }
                                else
                                {        //学生的学号为排序因素
                                        SortKey1 = atoi(View_1->num);
                                        SortKey2 = atoi(View_2->num);
                                        result = (SortKey1)>(SortKey2)? 1:0;
                                }
                                if(result)
                                {
                                //        printf("%\n%s与%s交换",View_1->num,View_2->num);
                                        View_0->pnext = View_2;
                                        View_1->pnext = View_2->pnext;
                                        View_2->pnext = View_1;        
                                        
                                        View_1 = View_2;
                                        View_2 = View_1->pnext;
                                        

                                }
                                if(View_2->pnext!=NULL)                                        
                                {
                                        View_0 = View_0->pnext;
                                        View_1 = View_0->pnext;
                                        View_2 = View_1->pnext;
                                }
                                
                                //如果最后节点的pnext是空,证明排序完毕,不需要再递进了
                        }
                }
                                printf("\n排序完毕\n");
                        
        }


        
}
//保存信息
void save_file()                                                                
{        
        FILE *file=NULL;
        STU* vIew = NULL;


        file = fopen("C:\\student_file.txt","w+");
        if(file==NULL)
                printf("文件打开失败!\n");
        
        vIew = (STU *)malloc(sizeof(STU));

        vIew->pnext=pStu->pnext;
        while(vIew->pnext!=NULL)
        {
        fputs(vIew->pnext->num,file);
        fputc(0x20,file);
        fputs(vIew->pnext->name,file);
        fputc(0x20,file);
        fputs(vIew->pnext->chinese,file);
        fputc(0x20,file);
        fputs(vIew->pnext->math,file);
        fputc(0x20,file);
        vIew->pnext=vIew->pnext->pnext;
        }
        free(vIew);
        vIew=NULL;        
        
        fputs("END_OF_FILE",file);
        fputc(0x20,file);

        fclose(file);
}
//从文件读入信息
void read_file()                                                                
{        
        int i=0;

        
        FILE *file=NULL;
        file = fopen("C:\\student_file.txt","r");

        if(file==NULL)
        {
                save_file();
                file = fopen("C:\\student_file.txt","r");
        }

        rewind(file);

        pCurrent ->pnext =pStu;
                
        while(1)
        {        pNew = (STU *)malloc(sizeof(STU));
                pNew->pnext = NULL;


                fscanf(file,"%s",pNew->num);
                if(strcmp(pNew->num,"END_OF_FILE")==0)        break;

                fscanf(file,"%s",pNew->name);
                fscanf(file,"%s",pNew->chinese);
                fscanf(file,"%s",pNew->math);
                
                
                pCurrent->pnext->pnext=pNew;                        
                pCurrent->pnext = pCurrent->pnext->pnext;
                //pCurrent->pnext指向现在存在的节点
        
        }
        fclose(file);

}
//短暂延时效果
void Delay()                                                                                                                        
{
        int i = 0;
        int j = 0;

        for(i=50000;i>0;i--)
                for(j=5000;j>0;j--)
                        ;
}
//系统初始化
void init()                
{
        pStu = (STU *)malloc(sizeof(STU));                                        //创建头节点
        pStu->pnext  =NULL;
        strcpy(pStu->num, "0");
        strcpy(pStu->name, " ");

        pCurrent = (STU *)malloc(sizeof(STU));
        pCurrent ->pnext =NULL;

        read_file();

}
//欢迎使用
void Welcome()                                                                        
{        system("cls");
        
        printf("\n\n\t┌================================================┑\n");
        printf("\n\n");
        printf("\t\t★★★欢迎使用学生信息管理系统★★★\n\n\n");
        printf("\t\t\t1.查看信息\n");
        printf("\t\t\t2.增加信息\n");
        printf("\t\t\t3.查找信息\n");
        printf("\t\t\t4.修改信息\n");
        printf("\t\t\t5.删除信息\n");
        printf("\t\t\t6.学生排序\n");
        printf("\t\t\t7.数据统计\n");
        printf("\t\t\t8.退出系统\n");
        printf("\n\n\t┕================================================┚\n");
}
/************************************主函数************************************/
int main()
{
        char choice  = 0;
        char AddYorN = 0;

        init();
        InCheck();
        Welcome();
//        MessageBox(0, "", 0);

                                                                                                                        //命令解释
        
        while(choice!='8')
        {        
                printf("\n>>");                                                                                //输入命令
                choice=getch();
                printf("%c",choice);

                switch(choice)
                {
                        case '1':ShowInformation();                
                                break;
                        case '2':        do
                                                {
                                                        AddInformation();        save_file();
                                                        printf("输入N可以退出增加信息.任意键继续输入\n");AddYorN=getch();printf("%c",AddYorN);
                                                }while(AddYorN!='N');
                                break;        
                        case '3':Search();
                                break;        
                        case '4':Modify();        save_file();        
                                break;
                        case '5':Delete();        save_file();
                                break;
                        case '6':Sort();        save_file();
                                break;
                        case '7':Statistical();
                                break;
                        case '8':
                                break;
                        default:printf("\t\t任意键返回主菜单\n");getch();Welcome();
                        
                }
}
        
    system("cls");
        system("color 81");
        printf("\n\t\t感谢您的使用,再见!\n");
        Delay();

        
        save_file();
        return 0;

}

查看所有文章

完美的Microsoft Visual C++ 6.0 (简称VC6.0)

注意!该软件目前系统已知不兼容Windows 10操作

Microsoft Visual C++,(简称Visual C++、MSVC、VC++或VC)是Microsoft公司推出的以C++语言为基础的开发Windows环境程序,面向对象的可视化集成编程系统。它不但具有程序框架自动生成、灵活方便的类管理、代码编写和界面设计集成交互操作、可开发多种程序等优点,而且通过的设置就可使其生成的程序框架支持数据库接口、OLE2.0,WinSock网络。[1]

Microsoft Visual C++ 6.0,简称VC6.0,是微软于1998年推出的一款C++编译器,集成了MFC
 6.0,包含标准版(Standard Edition)、专业版(Professional Edition)与企业版(Enterprise Edition)[2]
 。发行至今一直被广泛地用于大大小小的项目开发。(但是,这个版本在Windows XP
下运行会出现问题,尤其是在调试模式的情况下(例如:静态变量的值并不会显示)。这个调试问题可以通过打一个叫“Visual C++ 6.0 Processor Pack”的补丁[3]
 来解决。)

链接: https://pan.baidu.com/s/1bp4JsWB 密码: kyst