学生管理系统
翻出了以前C语言C实验的大作业,当时搞了好多奇技淫巧,最终拿到99分。

翻出了以前C语言C实验的大作业,当时搞了好多奇技淫巧,最终拿到99分。

介绍

学生成绩管理系统v6.0是由软件工程1702刘海鑫设计的一款用于学生成绩管理的软件。

文件列表

  • Stuv6.0.exe 主体程序,用于实现整体功能。
  • main.dat 程序的数据文件,用于存储学生信息。
  • goodbye.bmp 程序退出时加载的图片。
  • desktop.ini 修改程序所在文件夹的图标。
  • consoletest.exe 编译的au3程序,用于辅助输入中文。

代码:

$re=InputBox("Input","You can input your massage now.(支持中文)")
ConsoleWrite($re)
  • code.dat 密码存储文件。该文件存储的是xor算法加密的账号密码。
  • black.bmp 一张纯黑的图片,用于清除控制台加载图片的痕迹。2018年1月20日使用了image /d清除图片,本文件不再使用。
  • background.bmp 程序启动时加载的图片。
  • about.rtf 程序的说明文档。
  • scaned.txt 存储用户输入的临时文件,一般会自动清除。
  • subjects.dat 存储科目的名称,每行一个,最多允许50个,可用记事本直接打开编辑。
  • image.exe 外部程序,用于加载图片。

使用说明

双击stuv6.0.exe,程序启动。

待启动图片显示过后,出现密码输入框,回车确认输入。

默认账号:admin

默认密码:admin888

输入密码时如果输入~符号,将弹出一个信息框提示输入。这是为了便于输入中文和特殊符号。

本程序的密码存储是xor运算的结果,仅用于比对密码是否正确。

接下来进入主菜单。菜单使用黄色为底色,红色标定选中项。你可以按上下键选择,或直接按项目对应数字,回车确认。

开发日志

  • 2018年3月10日,加入了控制台窗口大小控制的代码。

  • 修改了exe文件的图标。

  • 改用外部程序image.exe加载图片,并修改gotoxy函数的使用,成功使代码兼容了gun gcc系列编译器。

  • 测试WIN7运行效果,图片加载错位,无法全屏,其他功能不受影响。

  • 在科目分析功能加入分层成绩展示,至此,程序主体开发完毕。

  • 加入查找功能,查找方式为遍历,依据为id或姓名。 同理,加入按id排序、按姓名的字典顺序排序。 数据排序功能,选择后弹出二级菜单,进行升序排序或降序排序。 排序的结果不会保存。 排序后将自动展示排序结果。

  • 加入了科目分析,统计各科总分平均分。

  • 删除学生功能准备完成。

  • 将修改密码部分移出主函数,便于管理。

  • 学生信息展示准备完成。

  • 添加学生功能准备完成,界面比较简陋。

  • 发现有点控制台用BitBlt画的图不会自动清除,于是找了一张全黑的图片将其覆盖。

  • 发现在WIN7等系统控制台加载图片会出现错位,暂时不打算解决。

  • 开始准备程序主体功能。

  • 记事本太单调,决定将about改为写字板,内容为本文件。

  • 发现了atexit函数,于是顺理成章地加入了程序退出图。

  • 找到一个取巧的方法。控制台也是一个窗口,获取了他的句柄就可以在上面用BitBlt直接画图了吧。

  • 决定加入加载启动退出图片功能。可是Windows环境下C语言直接调用GDI常常导致系统蓝屏。虽然直接用其他语言就可以轻松写出,但总是有点不甘心。

  • 加入了about,system(“notepad.exe about.txt”)实现。

  • 加入了密码修改功能。

  • 发现并修正了“窗口”覆盖时的一个BUG。

  • 成功实现菜单功能!上下键控制菜单移动,回车选择目标。亦可直接按选项对应数字移动菜单项。函数原型:int showMenu(char txt[][50],int n,int selected,int X,int Y) txt是各菜单的文本。 n是菜单项总数目。 selected为当前选中项。 X,Y为菜单加载的坐标。 函数返回值为用户最终选定项。

  • 发现getch对中文兼容不好。为了方便输入中文密码,用AU3写了控制台程序:

  • 在getch检测到用户输入~后即打开该程序输入数据。

  • 制作了密码登录界面,用户名用fgets扫描,password用getch检测。getch检测到后输出*。

  • 调用前面的函数实现了伪信息框(图左),虽然和系统的信息框(图右)没得比,但在控制台下做出这个水平我还是知足了。

  • UE的控制台与程序兼容性实在不行,改用code blocks作为IDE,编译器使用gcc for windows。

  • 通过gotoxy和严格的坐标计算实现了绘制伪窗口功能。

  • 发现了函数gotoxy(x,y),可以控制光标输出位置,但好像移植性不好,比如GUN系列编译器就是另一个函数。决定还是使用。

  • 最终暂时选定XOR算法,代码:

  • 准备用户登录验证方案,由经验打算采用XOR算法或MD5算法。

  • 找到了合理的颜色控制方案,但似乎并不是所有控制台都能使用(UltraEdit DOS Command就不能用),不过暂时就这样了。

  • 决定将界面制作得精美一些。查找资料。找到DOS命令color可以改控制台颜色方案,但只能同时更改整个控制台的颜色,怎么看都不舒服,放弃。

  • 找到DOS指令title可以直接修改控制台标题。控制台标题改为“学生成绩管理系统V6.0”。

  • 选定课题为学生成绩管理系统,总体难度不大,毕竟书上范例改一改就是标准答案了。但我决定还是挑战一下。

#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include <windows.h>
//#include <conio.h>
#include "math.h"
void miniMessage(char*msg);
void showExitPic();
/*
typedef HWND (WINAPI *PROCGETCONSOLEWINDOW)();//图片加载
PROCGETCONSOLEWINDOW GetConsoleWindow;
*/
void PrintChar(char *ch,UINT count,UINT x,UINT y)  //在坐标(x,y)处输出字符串ch,ch里有count个字符
{
    HANDLE h=GetStdHandle(STD_OUTPUT_HANDLE);
    COORD pos;
    ULONG unuse;
    pos.X=x;
    pos.Y=y;
    CONSOLE_SCREEN_BUFFER_INFO bInfo; // 窗口缓冲区信息
    GetConsoleScreenBufferInfo(h, &bInfo );
    WriteConsoleOutputCharacterA(h,ch,count,pos,&unuse);
}
void color(short x) //自定义函根据参数改变颜色
{
    if(x>=0 && x<=15)//参数在0-15的范围颜色
        SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), x);    //只有一个参数,改变字体颜色
    else//默认的颜色白色
        SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 7);
    /*
    颜色函数SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),前景色 | 背景色 | 前景加强 | 背景加强);
        前景色:数字0-15 或 FOREGROUND_XXX 表示  (其中XXX可用BLUE、RED、GREEN表示)
        前景加强:数字8 或 FOREGROUND_INTENSITY 表示
        背景色:数字16 32 64 或 BACKGROUND_XXX 三种颜色表示
        背景加强: 数字128 或 BACKGROUND_INTENSITY 表示
    主要应用:改变指定区域字体与背景的颜色
    前景颜色对应值:
      0=黑色                8=灰色  
       1=蓝色                9=淡蓝色        十六进制          
      2=绿色                10=淡绿色       0xa          
      3=湖蓝色              11=淡浅绿色     0xb 
      4=红色                12=淡红色       0xc  
      5=紫色                13=淡紫色       0xd          
      6=黄色                14=淡黄色       0xe          
      7=白色                15=亮白色       0xf
      也可以把这些值设置成常量。
    */
}
void gotoxy(unsigned char x,unsigned char y)
{
    //COORD是Windows API中定义的一种结构,表示一个字符在控制台屏幕上的坐标
    COORD cor;
    //句柄
    HANDLE hout;
    //设定我们要定位到的坐标
    cor.X = x;
    cor.Y = y;
    //GetStdHandle函数获取一个指向特定标准设备的句柄,包括标准输入,标准输出和标准错误。
    //STD_OUTPUT_HANDLE正是代表标准输出(也就是显示屏)的宏
    hout = GetStdHandle(STD_OUTPUT_HANDLE);
    //SetConsoleCursorPosition函数用于设置控制台光标的位置
    SetConsoleCursorPosition(hout, cor);
}
typedef struct
{
    char name[25];
    char sex;
    int age;
    int id;
    int subjects[50];
    int sum;
    int avg;
} student;
char sub_name[50][25];
student stu_dat[10000];
int dat_count;
int sub_count;
int Login(char*c1,char*c2)
{
    FILE*fp;
    char*p1;
    char*p3;
    char*p2;
    int tmp;
    fp=fopen("code.dat","r");
    p1=c1;
    p3=c2;
    if(strlen(c1)>strlen(c2))
    {
        p2=p1;
        p1=p3;
        p3=p2;
    }
    for (; *p3!='\0'; )
    {
        if(*p1=='\0')
        {
            p1=c1;
        }
        tmp=fgetc(fp);
        if(((*p1)^(*p3))!=tmp)
        {
            return 0;
        }
        p1++;
        p3++;
    }
    if(strlen(c1)<2||strlen(c2)<6)
    {
        return 0;
    }
    return 1;
    fclose(fp);
}
void savePwd(char*c1,char*c2)
{
    FILE*fp;
    fp=fopen("code.dat","w");
    char*p1=c1;
    char*p2=c2;
    char*p3;
    if(strlen(c1)>strlen(c2))
    {
        p3=p1;
        p1=p2;
        p2=p3;
    }
    for (; *p2!='\0'; )
    {
        if(*p1=='\0')
        {
            p1=c1;
        }
        fputc((*p1)^(*p2),fp);
        p1++;
        p2++;
    }
    fclose(fp);
}
void dat_add(student*s1)
{
    FILE*fp;
    s1->sum=0;
    for (int i=0; i<sub_count; i++)
    {
        s1->sum+=s1->subjects[i];
    }
    s1->avg=s1->sum/=sub_count;
    fp=fopen("main.dat","ab");
    if(fp==NULL)
    {
        fp=fopen("main.dat","wb");
    }
    fwrite(s1,sizeof(student),1,fp);
    fclose(fp);
}
void sub_load()
{
    FILE*fp;
    fp=fopen("subjects.dat","r");
    sub_count=0;
    for (int i=0; i<50; i++)
    {
        fgets(sub_name[i],sizeof(sub_name),fp);
        sub_name[i][strlen(sub_name[i])-1]='\0';
        if(strlen(sub_name[i])>0)
        {
            sub_count++;
        }
    }
    fclose(fp);
}
void sub_print()
{
    printf("学号\t姓名\t性别\t年龄\t");
    for (int i=0; i<50; i++)
    {
        if(strlen(sub_name[i])==0)
        {
            break;
        }
        printf("%s\t",sub_name[i]);
    }
    printf("总分\t平均分\t排名\t");
    putchar('\n');
}
int dat_load()
{
    FILE*fp;
    int i;
    fp=fopen("main.dat","rb");
    if(fp==NULL)
    {
        puts("main.dat is lost!");
        exit(1);
    }
    for (i=0; !feof(fp) ; i++)
    {
        fread(&stu_dat[i],sizeof(student),1,fp);
    }
    fclose(fp);
    return i-1;
}
void dat_show (student s)
{
    printf("%d\t%s\t%c\t%d\t",s.id,s.name,s.sex,s.age);
    for (int i=0; i<sub_count; i++)
    {
        printf("%d\t",s.subjects[i]);
    }
    printf("%d\t%d\t",s.sum,s.avg);
}
void showMiniWindow(char*title,int X,int Y,int height,int width)
{
    for(int i=0; i<width; i++)
    {
        for(int i2=0; i2<height; i2++)
        {
            gotoxy(X+i,Y+i2);
            putchar(' ');
        }
    }
    color(3);
    gotoxy(X,Y);
    putchar('X');
    gotoxy(X+width-1,Y);
    putchar('X');
    gotoxy(X,Y+height-1);
    putchar('X');
    gotoxy(X+width-1,Y+height-1);
    putchar('X');
    color(5);
    for (int i=2; i<width; i++)
    {
        gotoxy(X+i-1,Y);
        putchar('-');
        gotoxy(X+i-1,Y+height-1);
        putchar('-');
    }
    color(9);
    for (int i=2; i<height; i++)
    {
        gotoxy(X,Y+i-1);
        putchar('|');
        gotoxy(X+width-1,Y+i-1);
        putchar('|');
        PrintChar("|",1,X+width-1,Y+i-1);
    }
    color(12);
    gotoxy(X+width/2-strlen(title)/2,Y);
    printf("%s",title);
    color(16);
    gotoxy(X+1,Y+1);
}
void miniLogin ()
{
    char c1[25],c2[25];
    char ch_tmp;
    char*p=c2;
    FILE*fp;
    showMiniWindow("login",6,5,4,32);
    puts("User     ________________");
    gotoxy(7,7);
    puts("password ________________");
    gotoxy(16,6);
    fgets(c1,sizeof(c1),stdin);
    c1[strlen(c1)-1]='\0';
    gotoxy(16,7);
    while(1)
    {
        ch_tmp=getch();
        if(ch_tmp==13)
        {
            *p='\0';
            break;
        }
        else if(ch_tmp=='~')
        {
            system("consoletest.exe>scaned.txt");
            fp=fopen("scaned.txt","r");
            fgets(c2,sizeof(c2),fp);
            fclose(fp);
            system("del scaned.txt");
            break;
        }
        else
        {
            *p=ch_tmp;
            p++;
            putchar('*');
        }
    }
    if(Login(c1,c2))
    {
        miniMessage("登录成功,欢迎您的使用!");
    }
    else
    {
        miniMessage("用户名或密码错误!");
        Sleep(1000);
        showExitPic();
        exit(1);
    }
    Sleep(1000);
}
void miniMessage(char*msg)
{
    int n=strlen(msg);
    int width=(int)sqrt(n)+10;
    int height=n/(width-2)+4;
    int X=5;
    int Y=7;
    showMiniWindow("Message",X,Y,height,width);
    X++;
    Y++;
    for (int i=0; i<n; i++)
    {
        putchar(msg[i]);
        if(i%(width-2)==0)
        {
            Y++;
            gotoxy(X,Y);
        }
    }
}
int showMenu(char txt[][50],int n,int selected,int X,int Y)
{
    int maxwidth=0;
    int tmp_width;
    char tmp_press;
    for(int i=0; i<n; i++)
    {
        tmp_width=strlen(txt[i]);
        if(tmp_width>maxwidth)
        {
            maxwidth=tmp_width;
        }
    }
    showMiniWindow("MENU",X,Y,n+2,maxwidth+2);
    for(int i=0; i<n; i++)
    {
        if(i==selected)
        {
            color(4);
        }
        else
        {
            color(6);
        }
        for(int i2=0; txt[i][i2]!='\0'; i2++)
        {
            gotoxy(X+i2+1,Y+i+1);
            putchar(txt[i][i2]);
        }
    }
    color(16);
    tmp_press=getch();
    if(tmp_press==13)
    {
        return selected;
    }
    else if(tmp_press==72)
    {
        if(selected>0)
        {
            selected--;
        }
        else
        {
            putchar('\a');
        }
    }
    else if(tmp_press==80)
    {
        if(selected<n-1)
        {
            selected++;
        }
        else
        {
            putchar('\a');
        }
    }
    else if(tmp_press-'0'>=0&&tmp_press-'0'<n)
    {
        selected=tmp_press-'0';
    }
    return showMenu(txt,n,selected,X,Y);
}
/*
void picLoad(char*path)
{
    HMODULE hKernel32 = GetModuleHandle("kernel32");
    GetConsoleWindow= (PROCGETCONSOLEWINDOW)GetProcAddress(hKernel32,"GetConsoleWindow");
    HWND cmd=GetConsoleWindow();
    HDC dc = GetDC(cmd);
    HBITMAP hBitmap;
    hBitmap=(HBITMAP)LoadImage            (NULL,path,IMAGE_BITMAP,0,0,LR_LOADFROMFILE|LR_CREATEDIBSECTION);
    HDC cmdmem = CreateCompatibleDC(dc);
    SelectObject(cmdmem, hBitmap);
    BitBlt(dc, 0, 0, 1300, 700, cmdmem, 0, 0, SRCCOPY);
    Sleep(3000);
    return ;
}*/
/*
void loadBlack()
{
    HMODULE hKernel32 = GetModuleHandle("kernel32");
    GetConsoleWindow= (PROCGETCONSOLEWINDOW)GetProcAddress(hKernel32,"GetConsoleWindow");
    HWND cmd=GetConsoleWindow();
    HDC dc = GetDC(cmd);
    HBITMAP hBitmap;
    hBitmap=(HBITMAP)LoadImage            (NULL,"black.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE|LR_CREATEDIBSECTION);
    HDC cmdmem = CreateCompatibleDC(dc);
    SelectObject(cmdmem, hBitmap);
    BitBlt(dc, 0, 0, 1300, 700, cmdmem, 0, 0, SRCCOPY);
    return ;
}
*/
void showExitPic()
{
    system("image goodbye.bmp 0 0");
    Sleep(3000);
    //picLoad("goodbye.bmp");
}
void add_stu()
{
    char tmp_sex[10];
    student tmp;
    system("cls");
    printf("Please input the id number of the new student.\n");
    scanf("%d",&tmp.id);
    printf("Please input the name of the student.\n");
    scanf("%s",tmp.name);
    printf("Please input the sex of the student.(F for Female,M for Male.)\n");
    scanf("%s",tmp_sex);
    if(strcmp(tmp_sex,"F")==0)
    {
        tmp.sex='F';
    }
    else
    {
        tmp.sex='M';
    }
    printf("Please input the age of the student.\n");
    scanf("%d",&tmp.age);
    for(int i=0; i<sub_count; i++)
    {
        printf("Please input %s's %s score.\n",tmp.name,sub_name[i]);
        scanf("%d",&tmp.subjects[i]);
    }
    dat_add(&tmp);
    dat_count=dat_load();
    printf("Data added successfully!\n");
    Sleep(3000);
}
void showalldata()
{
    system("cls");
    sub_print();
    for(int i=0; i<dat_count; i++)
    {
        printf("%d\t%s\t%c\t%d\t",stu_dat[i].id,stu_dat[i].name,stu_dat[i].sex,stu_dat[i].age);
        for(int i2=0; i2<sub_count; i2++)
        {
            printf("%d\t",stu_dat[i].subjects[i2]);
        }
        printf("%d\t%d\t%d\t\n",stu_dat[i].sum,stu_dat[i].avg,i+1);
    }
    system("pause");
}
void ed_password()
{
    char us_name[50];
    char us_pwd[50];
    char us_pwd2[50];
    char us_pwd3[50];
    char*p;
    FILE*fp;
    system("cls");
    showMiniWindow("修改密码",5,7,6,36);
    puts("UserName");
    gotoxy(6,9);
    puts("PassWord");
    gotoxy(6,10);
    puts("NewPassWord");
    gotoxy(6,11);
    puts("Again");
    gotoxy(18,8);
    scanf("%s",us_name);
    gotoxy(18,9);
    p=us_pwd;
    while(1)
    {
        *p=getch();
        if(*p==13)
        {
            p--;
            break;
        }
        else if(*p=='~')
        {
            system("consoletest.exe>scaned.txt");
            fp=fopen("scaned.txt","r");
            fgets(us_pwd,sizeof(us_pwd),fp);
            fclose(fp);
            system("del scaned.txt");
            break;
        }
        else
        {
            putchar('*');
            p++;
        }
    }
    gotoxy(18,10);
    p=us_pwd2;
    while(1)
    {
        *p=getch();
        if(*p==13)
        {
            p--;
            break;
        }
        else if(*p=='~')
        {
            system("consoletest.exe>scaned.txt");
            fp=fopen("scaned.txt","r");
            fgets(us_pwd2,sizeof(us_pwd2),fp);
            fclose(fp);
            system("del scaned.txt");
            break;
        }
        else
        {
            putchar('*');
            p++;
        }
    }
    gotoxy(18,11);
    p=us_pwd3;
    while(1)
    {
        *p=getch();
        if(*p==13)
        {
            p--;
            break;
        }
        else if(*p=='~')
        {
            system("consoletest.exe>scaned.txt");
            fp=fopen("scaned.txt","r");
            fgets(us_pwd3,sizeof(us_pwd3),fp);
            fclose(fp);
            system("del scaned.txt");
            break;
        }
        else
        {
            putchar('*');
            p++;
        }
    }
    if(Login(us_name,us_pwd)&&strcmp(us_pwd2,us_pwd3)==0)
    {
        savePwd(us_name,us_pwd2);
        miniMessage("Password modification success");
    }
    else
    {
        miniMessage("Password modification failed,please check you input.");
    }
    Sleep(3000);
    system("cls");
}
void del_dat()
{
    int tmp_number;
    char str_cmd[255];
    system("cls");
    printf("Please input the id of the data.\n");
    printf("System will delete the first data founded.\n");
    scanf("%d",&tmp_number);
    for(int i=0; i<dat_count; i++)
    {
        if(stu_dat[i].id==tmp_number)
        {
            printf("Data founded.Are you sure to delete it?(Y/N)\n");
            scanf("%s",str_cmd);
            if(strcmp(str_cmd,"Y")!=0&&strcmp(str_cmd,"y")!=0)
            {
                printf("Command canceled.\n");
                system("pause");
                return;
            }
            stu_dat[i]=stu_dat[dat_count-1];
            dat_count--;
            system("del main.dat");
            for(int i2=0; i2<dat_count; i2++)
            {
                dat_add(&stu_dat[i]);
            }
            printf("Del successfully!\n");
            system("pause");
            return;
        }
    }
    miniMessage("Cannot found target data!");
    system("pause");
}
void sub_ana()
{
    system("cls");
    int tmp_sum[50];
    int tmp_avg[50];
    int tmp_level[50][5];
    for(int i=0; i<50; i++)
    {
        tmp_sum[i]=0;
        tmp_avg[i]=0;
        for(int i2=0; i2<5; i2++)
        {
            tmp_level[i][i2]=0;
        }
    }
    for(int i=0; i<dat_count; i++)
    {
        for(int i2=0; i2<sub_count; i2++)
        {
            tmp_sum[i2]+=stu_dat[i].subjects[i2];
            switch(stu_dat[i].subjects[i2]/10)
            {
            case 10:
            case 9:
                tmp_level[i][0]++;
                break;
            case 8:
                tmp_level[i][1]++;
                break;
            case 7:
                tmp_level[i][2]++;
                break;
            case 6:
                tmp_level[i][3]++;
                break;
            default:
                tmp_level[i][4]++;
            }
        }
    }
    for(int i=0; i<sub_count; i++)
    {
        tmp_avg[i]=tmp_sum[i]/dat_count;
    }
    printf("科目\t总分\t平均分\t优秀\t良好\t中等\t及格\t不及格\t\n");
    for(int i=0; i<sub_count; i++)
    {
        printf("%s\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t\n",sub_name[i],tmp_sum[i],tmp_avg[i]
               ,tmp_level[i][0],tmp_level[i][1],tmp_level[i][2],tmp_level[i][3]
               ,tmp_level[i][4]);
    }
    system("pause");
}
int cmpbysum1(const void *p1,const void *p2)
{
    return ((student*)p1)->sum-((student*)p2)->sum;
}
int cmpbysum2(const void *p1,const void *p2)
{
    return ((student*)p2)->sum-((student*)p1)->sum;
}
void sortbysum()
{
    //ascending sort升序排序
    //descending sort降序排序
    char mnu[][50]= {"Ascending sort↑","Descending sort↓","Cancel"};
    int m_resu;
    m_resu=showMenu(mnu,3,0,7,7);
    system("cls");
    switch(m_resu)
    {
    case 0:
        qsort(stu_dat,dat_count,sizeof(student),cmpbysum1);
        break;
    case 1:
        qsort(stu_dat,dat_count,sizeof(student),cmpbysum2);
        break;
    default:
        printf("Command canceled.\n");
        system("pause");
        return;
    }
    printf("OK.\n");
    system("pause");
    showalldata();
}
int cmpbyid1(const void *p1,const void *p2)
{
    return ((student*)p1)->id-((student*)p2)->id;
}
int cmpbyid2(const void *p1,const void *p2)
{
    return ((student*)p2)->id-((student*)p1)->id;
}
void sortbyid()
{
    char mnu[][50]= {"Ascending sort↑","Descending sort↓","Cancel"};
    int m_resu;
    m_resu=showMenu(mnu,3,0,7,7);
    system("cls");
    switch(m_resu)
    {
    case 0:
        qsort(stu_dat,dat_count,sizeof(student),cmpbyid1);
        break;
    case 1:
        qsort(stu_dat,dat_count,sizeof(student),cmpbyid2);
        break;
    default:
        printf("Command canceled.\n");
        system("pause");
        return;
    }
    printf("OK.\n");
    system("pause");
    showalldata();
}
int cmpbyname(const void *p1,const void *p2)
{
    return strcmp(((student*)p1)->name,((student*)p2)->name);
}
void sortbyname()
{
    system("cls");
    qsort(stu_dat,dat_count,sizeof(student),cmpbyname);
    printf("OK.\n");
    system("pause");
    showalldata();
}
void searchbyid()
{
    int tmp_id;
    int founded=0;
    system("cls");
    printf("Please input the id of the student.\n");
    scanf("%d",&tmp_id);
    system("cls");
    sub_print();
    for(int i=0; i<dat_count; i++)
    {
        if(stu_dat[i].id==tmp_id)
        {
            founded++;
            printf("%d\t%s\t%c\t%d\t",stu_dat[i].id,stu_dat[i].name,stu_dat[i].sex,stu_dat[i].age);
            for(int i2=0; i2<sub_count; i2++)
            {
                printf("%d\t",stu_dat[i].subjects[i2]);
            }
            printf("%d\t%d\t%d\t\n",stu_dat[i].sum,stu_dat[i].avg,founded);
        }
    }
    if(founded==0)
    {
        system("cls");
        printf("Not founded!\n");
    }
    system("pause");
}
void searchbyname()
{
    char tmp_name[25];
    int founded=0;
    system("cls");
    printf("Please input the name of the student.\n");
    scanf("%s",tmp_name);
    system("cls");
    sub_print();
    for(int i=0; i<dat_count; i++)
    {
        if(strcmp(stu_dat[i].name,tmp_name)==0)
        {
            founded++;
            printf("%d\t%s\t%c\t%d\t",stu_dat[i].id,stu_dat[i].name,stu_dat[i].sex,stu_dat[i].age);
            for(int i2=0; i2<sub_count; i2++)
            {
                printf("%d\t",stu_dat[i].subjects[i2]);
            }
            printf("%d\t%d\t%d\t\n",stu_dat[i].sum,stu_dat[i].avg,founded);
        }
    }
    if(founded==0)
    {
        system("cls");
        printf("Not founded!\n");
    }
    system("pause");
}
int main()
{
    atexit(showExitPic);
    int m_resu;
    char mnu[][50]= {"Modify the password","Add new data","Show all data",
                     "Del data by id","Subject analysis","Sort data by sum","Sort data by id"
                     ,"Sort in dictionary order by name","Search by id","Search by name"
                     ,"about","exit"
                    };
    system("title 学生成绩管理系统V6.0");
    system("mode con cols=100 lines=30");
    //picLoad("background.bmp");
    //loadBlack();
    system("image background.bmp 0 0");
    Sleep(3000);
    system("image /d");
    system("cls");
    miniLogin();
    system("cls");
    sub_load();
    dat_count=dat_load();
beg:
    m_resu=showMenu(mnu,12,0,5,6);
    switch(m_resu)
    {
    case 0:
        ed_password();
        break;
    case 1:
        add_stu();
        break;
    case 2:
        showalldata();
        break;
    case 3:
        del_dat();
        break;
    case 4:
        sub_ana();
        break;
    case 5:
        sortbysum();
        break;
    case 6:
        sortbyid();
        break;
    case 7:
        sortbyname();
        break;
    case 8:
        searchbyid();
        break;
    case 9:
        searchbyname();
        break;
    case 10:
        system("write about.rtf");
        break;
    case 11:
        goto end;
    }
    goto beg;
end:
    ;
}

最后修改于 2019-04-13