学生成绩管理系统(C)
 /*
 **********************************************************************************
 * 大一第一学期期末成绩管理系统
 *
 *  开发环境:VC++6.0
 *
 * 将全班学生成绩以记录的形式存储在文件中
 * 记录包含每个学生的姓名、学号、性别、三科(高等数学、大学英语、C语言)成绩
 * 程序功能:1.求各门课程总分、平均分;              2.求各个学生总分、平均分;
 *           3.按姓名、学号查找学生记录并显示;     4.浏览全部学生成绩;
 *
 * Author: 啊杜
 * email : [email protected]
 **********************************************************************************
 */
#include 
#include 
#include 
#define SUBJECT_NUMBER 3    //课程数目
#define SUBJECT_LENGTH 20   //课程名最大长度
#define NAME_LENGTH 20      //姓名最大长度
#define CODE_LENGTH 10      //学号最大长度
#define SEX 5   //性别长度
#define FILE_LENGTH 80      //文件名最大长度
#define BUFFER_LENGTH 80    //缓冲区最大长度
char subjectName[SUBJECT_NUMBER][SUBJECT_LENGTH] = {"高等数学", "大学英语", "C语言"}; //课程名称
int total[SUBJECT_NUMBER];  //各课程总分
char fileName[FILE_LENGTH];     //文件名
//结构——学生记录
struct record
{
    char name[NAME_LENGTH+1];       //姓名
    char code[CODE_LENGTH+1];       //学号
    char sex[SEX];  //性别
    int mark[SUBJECT_NUMBER+1]; //各科成绩
    int total;  //总分
}student;
//从指定文件读入一个记录
int ReadRecord (FILE *fpt, struct record *ppt)
{
    char buf[BUFFER_LENGTH];
    int i;
    if (1 != fscanf (fpt, "%s", buf))
    {
        printf ("文件 %s 无法打开!\n", fpt);
        return 0;
    }
    strncpy (ppt->name, buf, NAME_LENGTH);   //存储学生姓名
                                            
    fscanf (fpt, "%s", buf);
    strncpy (ppt->code, buf, CODE_LENGTH);   //存储学生学号
                                            
    fscanf (fpt, "%s", buf);
    strncpy (ppt->sex, buf, SEX);        //存储学生性别
                                            
    for (i = 0; i < SUBJECT_NUMBER; i++)
        fscanf(fpt, "%d", &ppt->mark[i]);    //存储学生各科成绩
                                                
    for (ppt->total = 0, i = 0; i < SUBJECT_NUMBER; i++)
        ppt->total += ppt->mark[i];       //计算学生总成绩
                                                
    return 1;
}
//对指定文件写入一个记录
void WriteRecord (FILE *fpt, struct record *ppt)
{
    int i;
                                            
    fprintf (fpt, "%s\n", ppt->name);    //写入学生姓名
                                            
    fprintf (fpt, "%s\n", ppt->code);    //写入学生学号
                                            
    fprintf (fpt, "%s\n", ppt->sex); //写入学生性别
                                            
    for (i = 0; i < SUBJECT_NUMBER; i++)
        fprintf(fpt, "%d\n", ppt->mark[i]);  //写入学生各科成绩
}
//显示某个学生的记录
void DisplayStudent (struct record *ppt)
{
    int i;
    printf ("\n姓名:  %s\n", ppt->name);   //显示姓名
                                            
    printf ("\n学号:  %s\n", ppt->code);   //显示学号
                                            
    printf ("\n性别:  %s\n", ppt->sex);    //显示性别
                                            
    printf ("各科成绩:\n");
    for (i = 0; i < SUBJECT_NUMBER; i++)
        printf ("%-s    :%d\n", subjectName[i], ppt->mark[i]);   //显示各科成绩
                                                
    printf ("\n总分:  %d\n", ppt->total);      //显示学生总分
                                            
    printf ("\n平均分: %.2f\n", (float)ppt->total / SUBJECT_NUMBER);    //显示学生平均分
}
//显示所有学生的记录
void ListStudent (char *fname)
{
    FILE *fp;
    struct record s;
    if (NULL == (fp = fopen(fname, "r")))
    {
        printf ("文件 %s 打不开!", fname);
        return ;
    }
    while (0 != ReadRecord (fp, &s))
    {
        DisplayStudent(&s);     //显示学生信息
                                                
        printf ("Press \"Enter\" to continue...");
        while ('\n' != getchar())
            ;
    }
    fclose(fp);
                                            
    return ;
}
//计算各科总分
int TotalMark (char *fname)
{
    FILE *fp;
                                            
    struct record s;
    int i, count = 0;
    if (NULL == (fp = fopen(fname, "r")))   //如果文件打不开,就退出
    {
        printf ("文件 %s 打不开!", fname);
        return 0;
    }
    for (i = 0; i < SUBJECT_NUMBER; i++) //初始化各科总分为0
        total[i] = 0;
    while (0 != ReadRecord (fp, &s))
    {
        for (i = 0; i < SUBJECT_NUMBER; i++)
            total[i] += s.mark[i];      //各科总分
        count++;    //有记录的学生人数
    }
    fclose(fp);
                                            
    return count;   //返回记录数
}
//按学生姓名查找记录
int RetrieveByName (char *fname, char *key)
{
    FILE *fp;
    int n = 0;
    struct record s;
    if (NULL == (fp = fopen(fname, "r")))
    {
        printf ("文件 %s 无法打开!\n", fname);
        return 0;
    }
    while (0 != ReadRecord (fp, &s))
    {
        if (0 == (strcmp (s.name, key)))        //按姓名查找某一个或多个学生
        {
            DisplayStudent (&s);        //显示某一个或多个学生的记录
            n++;
        }
    }
    fclose (fp);
    if (0 == n)
        printf ("学生 %s 不在文件 %s 中!\n", key, fname);
    return 1;
}
//按学生学号查找记录
int RetrieveByCode (char *fname, char *key)
{
    FILE *fp;
    int n = 0;
    struct record s;
    if (NULL == (fp = fopen(fname, "r")))
    {
        printf ("文件 %s 无法打开!\n", fname);
        return 0;
    }
    while (0 != ReadRecord (fp, &s))
    {
        if (0 == (strcmp (s.code, key)))    //按学号查找某一个学生
        {
            DisplayStudent (&s);        //显示某一个个学生的记录
            n++;
            break;
        }
    }
    fclose (fp);
    if (0 == n)
        printf ("学生 %s 不在文件 %s 中!\n", key, fname);
    else if (1 != n)
        printf ("学生 %s 学号被盗用!\n", key);
                                                
    return 1;
}
//主函数
main (void)
{
    FILE *fp;
    int i, j, n;
    char c;
    char buf[BUFFER_LENGTH];
    //int total[SUBJECT_NUMBER];
    struct record s;
    printf ("输入储存学生记录的文件名: ");
    scanf ("%s", fileName);
    if(NULL == (fp = fopen(fileName, "r")))
    {
        printf ("文件 %s  无法打开或不存在,你要建立一个吗?(Y/N) ", fileName);
        getchar();
        c = getchar();
        if('Y' == c || 'y' == c)
        {
            fp = fopen(fileName, "w");
            printf ("你要往文件中输入多少个记录: ");
            scanf ("%d", &n);
            for(i = 0; i < n; i++)
            {
                printf ("输入学生姓名: ");
                scanf ("%s", &s.name);
                printf ("输入学生学号: ");
                scanf ("%s", &s.code);
                printf ("输入学生性别:");
                scanf  ("%s", &s.sex);
                for(j = 0; j < SUBJECT_NUMBER; j++)
                {
                    printf ("输入 %s 成绩: ",subjectName[j]);
                    scanf ("%d", &s.mark[j]);
                }
                WriteRecord (fp, &s);
            }
            fclose(fp);
        }
    }
    fclose(fp);
    getchar();
    puts("现在可以输入命令来管理学生记录了!");
    puts("m : 各科平均分");
    puts("t : 各科总分");
    puts("n : 通过姓名查找学生记录");
    puts("c : 通过学号查找学生记录");
    puts("l : 查看全部学生记录");
    puts("q : 退出");
                                            
    while(1)
    {
        puts("输入命令:");
        scanf (" %c",&c);      
        if('q' == c || 'Q' == c)
        {
            puts("\n 谢谢使用(*^_^*).");
            break;      //结束程序运行
        }
        switch(c)
        {
            case 'm': //计算平均分
            case 'M':
                if(0 == (n = TotalMark(fileName)))
                {
                    puts("错误!");
                    break;
                }
                                                    
                printf ("\n");
                                                        
                for(i = 0; i < SUBJECT_NUMBER; i++)
                    printf ("%-s 的平均分: %.2f\n", subjectName[i], (float)total[i] / n);
                                                            
                break;
                                                        
            case 't': //计算总分
            case 'T':
                if(0 == (n = TotalMark (fileName)))
                {
                    puts("错误!");
                    break;
                }
                                                        
                printf ("\n");
                                                        
                for(i = 0; i < SUBJECT_NUMBER; i++)
                    printf("%-s 的总分: %d\n", subjectName[i], total[i]);
                                                            
                break;
                                                        
            case 'n': //按学生的姓名寻找记录
            case 'N':
                printf ("输入你要查询的学生的姓名: "); 
                scanf ("%s", buf);
                                                        
                RetrieveByName (fileName, buf); //按姓名查找的查询结果
                                                        
                break;
                                                        
            case 'c': // 按学生的学号寻找记录
            case 'C':
                printf ("输入你要查询的学生的学号: "); 
                scanf ("%s",buf);
                                                        
                RetrieveByCode (fileName,  buf);    //按学号查找的查询结果
                                                        
                break;
                                                        
            case 'l': // 列出所有学生记录
            case 'L':
                ListStudent (fileName);
                                                        
                break;
                                                        
            default:
                break;
        }
    }
    return 0;
}