• 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();
    }
  • 相关阅读:
    linux日常管理-screen
    linux日常管理-xarge_exec
    linux日常管理-linux日志
    linux日常管理-系统服务
    linux命令-任务计划-cron
    linux日常管理-防火墙netfilter工具-iptables-3
    linux日常管理-防火墙netfilter工具-iptables-2
    开启80端口
    linux日常管理-防火墙netfilter工具-iptables-1
    随机4位验证码
  • 原文地址:https://www.cnblogs.com/zemliu/p/2734395.html
Copyright © 2020-2023  润新知