C语言 学生信息管理系统

没写过C语言,学了一晚上C的结果,为交作业新鲜出炉的

环境是 Ubuntu. 编译器 gcc

#include<stdio.h>

#include<stdlib.h>

#include<memory.h>

#include<termio.h>



#define STDIN_FILENO 0

#define MAX_LEN   8

#define BACKSPACE 8

#define ENTER     13

#define ALARM     7

#define DATA_FILE "./data.txt"

#define USERNAME "root"

#define PASSWD "root"



/**

* 学生结构体

**/

typedef struct {

    char no[7];

    char name[9];

    char gender;

    float scores[3];

    float total_score;

    float avg_score;

} Student;



Student *stulist;  //所有学生列表

int stunum; //学生数量

char *stuproperty[7] = {

    "不指定",

    "学号",

    "姓名",

    "性别",

    "课程1",

    "课程2",

    "课程3"

};



/**

* 密码输出星号函数

**/

int getch() {

    struct termios tm, tm_old;

    int fd = STDIN_FILENO, c;

    if (tcgetattr(fd, &tm) < 0) return -1;

    tm_old = tm;

    cfmakeraw(&tm);

    if(tcsetattr(fd, TCSANOW, &tm) < 0) return -1;

    c = fgetc(stdin);

    if(tcsetattr(fd, TCSANOW, &tm_old) < 0) return -1;

    return c;

}



char *getpwd(const char *prompt)

{

    int i=0, ch;

    static char p[MAX_LEN+1]="";

    printf("%s", prompt);

    while((ch = getch())!= -1 && ch != ENTER)

    {

        if(i == MAX_LEN && ch != BACKSPACE)

        {

            putchar(ALARM);

            continue;

        }

        if(ch == BACKSPACE)

        {

            if(i==0)

            {

                putchar(ALARM);

                continue;

            }

            i--;

            putchar(BACKSPACE);

            putchar(' ');

            putchar(BACKSPACE);

        }

        else

        {

            p[i] = ch;

            putchar('*');

            i++;

        }

    }

    if(ch == -1)

    {

        while(i != -1)

        {

            p[i--] = '\0';

        }

        return NULL;

    }

    p[i]='\0';

    printf("\n");

    return p;

}



/**

* 登录验证

**/

void validate() {

    char *username = (char *) malloc(sizeof(char) * 8);

    printf("\n\t请输入用户名: ");

    scanf("%s", username);

    getchar();

    char *passwd = getpwd("\n\t请输入密码: ");

    if (strcmp(username, USERNAME) != 0 || strcmp(passwd, PASSWD) != 0) {

        printf("\n\t用户名或密码错误,程序即将退出\n");

        getchar();

        exit(0);

    }

}



/**

* 交换函数

**/

void swap(Student *stulist, int i, int j) {

    Student stutemp = stulist[i];

    stulist[i] = stulist[j];

    stulist[j] = stutemp;

}



/**

* 字符串重复函数

**/

char *strrep(char c, int n) {

    char *str = (char *) malloc(sizeof(c) * n + 1);

    int i;

    for (i = 0; i < n; i++) {

        *str++ = c;

    }

    *str = '\0';

    str -= n;

    return str;

}



/**

* 结果输出函数

**/

void print_result(Student *stulist, int stunum) {

    int i;

    float sum[3] = {0};

    float avg[3] = {0};

    float max[3] = {0};

    float min[3] = {

        stunum > 0 ? stulist[0].scores[0] : 0,

        stunum > 0 ? stulist[0].scores[1] : 0,

        stunum > 0 ? stulist[0].scores[2] : 0,

    };

    printf("\n\t位置\t学号\t姓名\t性别\t课程1\t课程2\t课程3\t总分\t平均分\n\n");

    for (i = 0; i < stunum; i++) {

        Student *s = &stulist[i];

        printf("\t%d\t%s\t%s\t%s\t%.1f\t%.1f\t%.1f\t%.1f\t%.1f\n", i, s->no, s->name, s->gender == '1' ? "" : "", s->scores[0], s->scores[1], s->scores[2], s->total_score, s->avg_score);

        sum[0] += s->scores[0];

        sum[1] += s->scores[1];

        sum[2] += s->scores[2];

        avg[0] = sum[0] / stunum;

        avg[1] = sum[1] / stunum;

        avg[2] = sum[2] / stunum;

        max[0] = s->scores[0] > max[0] ? s->scores[0] : max[0];

        max[1] = s->scores[1] > max[1] ? s->scores[1] : max[1];

        max[2] = s->scores[2] > max[2] ? s->scores[2] : max[2];

        min[0] = s->scores[0] < min[0] ? s->scores[0] : min[0];

        min[1] = s->scores[1] < min[1] ? s->scores[1] : min[1];

        min[2] = s->scores[2] < min[2] ? s->scores[2] : min[2];

    }



    //输出各科目成绩统计

    printf("\n\t\t最高分\t最低分\t总分\t平均分");

    printf("\n\t课程1\t%.1f\t%.1f\t%.1f\t%.f", max[0], min[0], sum[0], avg[0]);

    printf("\n\t课程2\t%.1f\t%.1f\t%.1f\t%.f", max[1], min[1], sum[1], avg[1]);

    printf("\n\t课程3\t%.1f\t%.1f\t%.1f\t%.f\n", max[2], min[2], sum[2], avg[2]);



}



/**

* 插入学生记录

**/

void add_stu() {

    Student stu;

    int no;

    printf("\n\t请输入插入的位置: ");

    scanf("%d", &no);

    printf("\n\t请输入学号: ");

    scanf("%s", stu.no);

    printf("\n\t请输入姓名: ");

    scanf("%s", stu.name);

    printf("\n\t请输入性别(1男2女): ");

    getchar();

    scanf("%c", &stu.gender);

    printf("\n\t请输入课程1成绩: ");

    scanf("%f", &stu.scores[0]);

    printf("\n\t请输入课程2成绩: ");

    scanf("%f", &stu.scores[1]);

    printf("\n\t请输入课程3成绩: ");

    scanf("%f", &stu.scores[2]);

    Student *s = &stu;

    stu.total_score = stu.scores[0] + stu.scores[1] + stu.scores[2];

    stu.avg_score = stu.total_score / 3;



    if (stulist == NULL) {

        stulist = (Student *) malloc(sizeof(Student));

    } else {

        stulist = (Student *) realloc(stulist, sizeof(Student) * (stunum + 1));

    }



    //插入指定编号位置

    if (no >= 0 && no < stunum) {

        memmove(&stulist[no + 1], &stulist[no], (stunum - no) * sizeof(Student));

    } else {

        //插到末尾

        no = stunum;

    }



    memcpy(&stulist[no], &stu, sizeof(Student));

    stunum++;

}



/**

* 查询学生

**/

void query_stu() {

    //输出查询菜单

    int i;

    for (i = 0; i < 7; i++) {

        printf("\n\t%d.%s", i + 1, stuproperty[i]);

    }

    printf("\n\n\t请输入查询条件编号: ");

    int choice;

    float low;

    float high;

    char *condition = (char *) malloc(sizeof(char) * 8);

    scanf("%d", &choice);

    switch(choice) {

        case 1: break;

        case 5:

        case 6:

        case 7:

            printf("\n\t请输入成绩下限: ");

            scanf("%f", &low);

            printf("\n\t请输入成绩上限: ");

            scanf("%f", &high);

            break;

        default:

            printf("\n\t请输入要查询的值: ");

            scanf("%s", condition);

    }



    //筛选符合条件的学生

    Student *sturesult = (Student *) malloc(sizeof(Student) * stunum);

    int resultnum = 0;

    for (i = 0; i < stunum; i++) {

        switch(choice) {

            case 2:

                if (strcmp(stulist[i].no, condition) == 0) 

                    sturesult[resultnum++] = stulist[i];

                break;

            case 3:

                if (strcmp(stulist[i].name, condition) == 0) 

                    sturesult[resultnum++] = stulist[i];

                break;

            case 4:

                if (stulist[i].gender == *condition) 

                    sturesult[resultnum++] = stulist[i];

                break;

            case 5:

            case 6:

            case 7:

                if (stulist[i].scores[choice - 5] >= low && stulist[i].scores[choice - 5] <= high)

                    sturesult[resultnum++] = stulist[i];

                break;

            default:

                sturesult[resultnum++] = stulist[i];

                break;

        }

    }



    //输出查询结果

    print_result(sturesult, resultnum);

}



/**

* 编辑学生

**/

void edit_stu() {

    int no;

    printf("\n\t请输入要编辑的学生位置: ");

    scanf("%d", &no);



    if (no < 0 || no >= stunum) no = 0;



    //输出编辑菜单

    int i;

    for (i = 1; i < 7; i++) {

        printf("\n\t%d.%s", i, stuproperty[i]);

    }



    int choice;

    char *value = (char *) malloc(sizeof(char) * 8);

    printf("\n\n\t请输入要编辑的属性编号: ");

    scanf("%d", &choice);

    printf("\n\t请输入要新的属性值: ");

    scanf("%s", value);



    //修改属性

    switch(choice) {

        case 1:

            memcpy(stulist[no].no, value, sizeof(char) * 7);

            break;

        case 2:

            memcpy(stulist[no].name, value, sizeof(char) * 9);

            break;

        case 3:

            stulist[no].gender = *value;

            break;

        case 4:

        case 5:

        case 6:

            stulist[no].scores[choice - 4] = atof(value);

            //重新计算平均成绩和总成绩

            stulist[no].total_score = stulist[no].scores[0] + stulist[no].scores[1] + stulist[no].scores[2];

            stulist[no].avg_score = stulist[no].total_score / 3;

            break;

        default:

            break;

    }

}



/**

* 删除学生

**/

void del_stu() {

    int no;

    printf("\n\t请输入要删除的学生的位置: ");

    scanf("%d", &no);

    if (no < 0 || no >= stunum) no = 0;

    memmove(&stulist[no],

            &stulist[no + 1],

            sizeof(Student) * (stunum - no - 1)

           );

    stunum--;

}



/**

* 学生排序

**/

void sort_stu() {

    //输出排序菜单

    int i;

    Student *sturesult = (Student *) malloc(sizeof(Student) * stunum);

    memcpy(sturesult, stulist, stunum * sizeof(Student));

    for (i = 1; i < 7; i++) {

        printf("\n\t%d.%s", i, stuproperty[i]);

    }



    int choice;

    printf("\n\n\t请输入要排序的字段编号: ");

    scanf("%d", &choice);

    

    //使用选择排序

    for (i = 0; i < stunum; i++) {

        int j;

        int min = i;

        for (j = i + 1; j < stunum; j++) {

            switch(choice) {

                case 1:

                    if (strcmp(sturesult[j].no, stulist[min].no) < 0) 

                        min = j;

                    break;

                case 2:

                    if (strcmp(sturesult[j].name, stulist[min].name) < 0) 

                        min = j;

                    break;

                case 3:

                    if (sturesult[j].gender < stulist[min].gender) 

                        min = j;

                    break;

                case 4:

                case 5:

                case 6:

                    if (sturesult[j].scores[choice - 4] < stulist[min].scores[choice - 4]) 

                        min = j;

                        break;

                default:

                    break;

            }

        }

        swap(sturesult, i, min);

    }



    //输出排序结果

    print_result(sturesult, stunum);



    //是否保存

    printf("\n\t请问是否需要保存排序结果(输入1/0): ");

    scanf("%d", &choice);

    if (choice == 1) {

        free(stulist);

        stulist = sturesult;

    } else {

        free(sturesult);

    }

}



/**

* 初始化,将数据文件读取进数组

**/

void init_sys() {

    FILE *fp = fopen(DATA_FILE, "rb");

    if (fp == NULL) {

        stunum = 0;

        stulist = NULL;

    } else {

        fread(&stunum, sizeof(int), 1, fp);

        stulist = (Student *) malloc(sizeof(Student) * stunum);

        fread(stulist, sizeof(Student), stunum, fp);

        fclose(fp);

    }

}



/**

* 程序结束,将数据写入文件

**/

void uinit_sys() {

    FILE *fp = fopen(DATA_FILE, "wb");

    fwrite(&stunum, sizeof(int), 1, fp);

    fwrite(stulist, sizeof(Student), stunum, fp);

    fclose(fp);

}



/**

* 成绩统计

**/

void statistics() {

    //3门课,每门课10个区间

    int courses[3][10] = {0};

    int i, j;

    for (i = 0; i < stunum; i++) {

        for (j = 0; j < 3; j++) {

            int q = (int) (stulist[i].scores[j] / 10);

            if (q > 9) q = 9;

            if (q < 0) q = 0;

            courses[j][q]++;

        }

    }



    for (i = 0; i < 3; i++) {

        printf("\n\n\t课程%d统计图: ", i + 1);

        printf("\n\t区间\t人数\t条形图");

        for (j = 0; j < 10; j++) {

            char *str = strrep('*', courses[i][j]);

            printf("\n\t%d-%d\t%d\t%s", j * 10, (j + 1) * 10 - 1, courses[i][j], str);

            free(str);

        }

    }

    printf("\n");

}



void main() {

    validate();

    init_sys();

    int flag = 1;

    while (flag) {

        char *menu[] = {

            "添加学生记录",

            "查询学生记录",

            "编辑学生记录",

            "删除学生记录",

            "排序学生记录",

            "统计学生记录",

            "退出系统"

        };



        //输出主菜单

        char *title = strrep('*', 33);

        printf("\n\t%s\t", title);

        int i;

        for (i = 0; i < 7; i++) {

            printf("\n\t*\t%d.%s\t\t*", i + 1, *(menu + i));

        }

        printf("\n\t%s\t\n\n", title);

        printf("\n\t请输入要执行的操作编号: ");

        

        //等待选择功能

        int choice;

        scanf("%d", &choice);

        switch (choice) {

            case 1: 

                add_stu();

                break;

            case 2: 

                query_stu();

                break;

            case 3: 

                edit_stu();

                break;

            case 4:

                del_stu();

                break;

            case 5:

                sort_stu();

                break;

            case 6: 

                statistics();

                break;

            default:

                flag = 0;

                printf("\n\tBye\n");

        }

    }

    uinit_sys();

}

你可能感兴趣的:(C语言)