学生成绩记录簿设计

学生成绩记录簿设计
编制一个C语言成绩记录簿,每个学生信息包括:学号、姓名、C语言成绩。
具体功能:
(1)创建信息链表并以磁盘文件保存;
(2)读取磁盘文件并显示输出所有学生的成绩;
(3)按学号或姓名查询成绩;
(4)添加成绩记录;
(5)修改指定姓名或学号的学生的成绩并可存盘;
(6)显示输出60分以下、60~79、80~89、90分以上各分数段的学生信息(可
选项)。

源代码:

#include<stdio.h>            // 头文件
#include<string.h>           //字符函数和字符串函数 strcmp
#include<stdlib.h>           //动态储存分配函数 malloc 

struct Student{
    char sno[20];    //学号
    char name[100];   //姓名 
    float grade;     //C语言成绩 
};

typedef struct Node{
    struct Student stu;                    //结构体变量(将以上信息封装到链表的结点当中) 
    struct Node *next;                    //下一个地址 
}Node,*StuLinkList;

//菜单显示函数 
void Menu(){
    printf("\t|---------------------------------------------------|\n");
    printf("\t|                 学生成绩管理薄系统                |\n"); 
    printf("\t|                                                   |\n");
    printf("\t|   自动读取信息至程序中(链表)                    |\n");
    printf("\t|---------------------------------------------------|\n");
    printf("\t|                     1.添加信息                    |\n");
    printf("\t|                     2.查询信息                    |\n");
    printf("\t|                     3.修改信息                    |\n");
    printf("\t|                     4.显示所有信息                |\n");
    printf("\t|                     5.显示分段信息                |\n");
    printf("\t|                     6.保存信息至文件              |\n");
    printf("\t|                     0.退出系统                    |\n");
    printf("\t|---------------------------------------------------|\n");
}

//分数菜单 
void gradeMenu(){
    printf("\t|---------------------------------------------------|\n");
    printf("\t|                 学生成绩分段表                    |\n"); 
    printf("\t|---------------------------------------------------|\n");
    printf("\t|                     1.60以下                      |\n");
    printf("\t|                     2.60~79                       |\n");
    printf("\t|                     3.80~89                       |\n");
    printf("\t|                     4.90以上                      |\n");
    printf("\t|---------------------------------------------------|\n");
}

//创建头结点
StuLinkList createHeadNode(){
    Node *head = NULL;
    head = (Node *)malloc(sizeof(Node));  //malloc是在堆上分配的地址  函数结束后 head的生存期还存在 因此可以返回结构体指针 
    if( !head ){
        printf("头结点分配失败!\n");                   //分配未成功说明内存不够,直接让函数结束 
        return NULL;
    }else{
        head->next = NULL;
    }
    return head;
}

//添加n个学生数据 (n从键盘输入) 
void addStuinfo(Node *head){
    int n;   //输入信息的个数 
    int i;   //用来for循环 
    printf("\n请输入初始化添加学生的个数:\n");
    scanf("%d",&n);
    for(i = 0;i < n;i++){
        Node *p = (Node *)malloc(sizeof(Node));
        p->next = NULL;   //指针先赋值为空 防止野指针的出现 
        printf("\n请输入第%d个学生学号、姓名、分数\n",i+1);
        scanf("%s%s%f",&p->stu.sno,&p->stu.name,&p->stu.grade);
        //头插法链接再头结点后面 
        p->next = head->next;   //将本来头结点的指针域的值(下一个结点的地址)赋值给在新结点指针域(相当于原来的结点链在了新结点上)  
        head->next = p;         //将新的结点链接在头结点后面(完成头插法) 
    }
    printf("\n添加成功!\n");
}

//查询学生成绩 
void searchStuinfo(Node *head){
    char temp[20];
    int flag = 0;   //标志找没找到 
    Node *p = head->next;                    //头结点无数据,无须遍历
    if(p == NULL){
        printf("此链表中无记录!\n ");
        return;
    }  
    printf("\n请输入要查询成绩的学生学号:");
    scanf("%s",&temp);
    while(p != NULL){
         if(strcmp(temp,p->stu.sno) == 0){  //strcmp函数
             flag = 1; 
             printf("\n-------------------------------------------------------------------------------------\n");
             printf("学号:%s\t\t",p->stu.sno);
             printf("姓名:%s\t\t",p->stu.name);
             printf("成绩:%.2f\n",p->stu.grade);   
            break;    
        }else{
            p = p->next;       //没找到往后遍历 
        }        
    }
    if(flag == 0){
        printf("\n不存在该学生信息!\n");
    }
    printf("\n");
} 

//输出所有链表元素 
void displayStuinfo(Node *head){
    Node *p = head->next;                    //头结点无数据,无须遍历
    if(p == NULL){
        printf("此链表中无记录!\n ");
        return;
    }  
    printf("\n-----------------------------------------------\n");
    printf("学号             姓名           成绩             \n");
    printf("-------------------------------------------------\n");
    while(p != NULL){
         //输出信息    
         printf("%s\t%s\t\t%.2f\n",p->stu.sno,p->stu.name,p->stu.grade);   //.2f为控制输出为小数点后两位  ///%15为控制输出间距 
         p = p->next;                               //每打印一次信息使其往后遍历 
    }
    printf("\n");
} 

//根据成绩分段输出链表元素 
void displaygradeStuinfo(Node *head){
    int choice;
    int flag = 0;  //标志 
    float fenshu1[4] = {0,60,80,90};  //分数下限数组 
    float fenshu2[4] = {59,79,89,100};  //分数上限数组
    Node *p = head->next;                    //头结点无数据,无须遍历
    if(p == NULL){
        printf("此链表中无记录!\n ");
        return;
    }  
    gradeMenu();
    printf("\n请输入选择:");
    scanf("%d",&choice);
    while(p != NULL){
        //判断 
         if(p->stu.grade >= fenshu1[choice-1] && p->stu.grade <= fenshu2[choice-1]){
             flag  = 1; 
             printf("\n-------------------------------------------------------------------------------------\n");
             printf("学号:%s\t\t",p->stu.sno);
             printf("姓名:%s\t\t",p->stu.name);
             printf("成绩:%.2f\n",p->stu.grade);       //.2f为控制输出为小数点后两位 
        }   
         p = p->next;                               //往后遍历 
    }
    if(flag == 0){
        printf("\n该分数段不存在学生!\n");
    }
    printf("\n");
}

//将文件中的数据读入到链表中
void readStuinfo(Node *head){
    Node *p1 = head;                       //p1指向的头结点
    Node *p2 = NULL;
    FILE *fp = NULL;   
    //fp = fopen("data.txt","r");  //文件指针
    fp = fopen("data.dat","rb");    //以r的方式  文件是data.txt 和当前代码所在路径一样  (相对路径) 
    if(fp == NULL){   //没在当前路径找到data文件 
        printf("本地不存在文件!\n\n");
        return;
    }
    while(1){  //死循环直到文件末尾   //feof = f end of file  到达文件末尾就break退出while循环 
        //开辟结点fscanf从文件读取数据 并链接在链表上   
        p2 = (Node *)malloc(sizeof(Node));
        fscanf(fp,"%s %s %f\n",&p2->stu.sno ,&p2->stu.name ,&p2->stu.grade);
        p2->next = NULL;  
        p1->next = p2;                            //将新建的p2结点的地址赋值给p1(头)结点的指针域,进行连接 
        p1 = p1->next; //p1后移在次从文本读取数据到链表                     
        if(feof(fp)){                              
            break;
        }
    }
    fseek(fp, 0, SEEK_SET);
    fclose(fp);   //关闭文件 
    printf("信息读取成功!\n");
} 

//将链表中的数据写入文件
void writeStuinfo(Node *head){
    struct Node *p = head->next;                  //头结点无数据不需要写入文件中
    FILE *fp = NULL;                              //文件指针
    //fp = fopen("data.dat","w"); 
    fp = fopen("data.dat","wb"); 
    while( p != NULL ){    //不到链表末尾就一直fprintf往文件里写数据 
        fprintf(fp,"%s %s% f\n",p->stu.sno ,p->stu.name ,p->stu.grade);
        p = p->next;
    }
    fseek(fp, 0, SEEK_SET);
    fclose(fp);//关闭文件
    printf("信息保存成功!\n");
}

//修改学生成绩 
void updateStuinfo(Node *head){
    char temp[20];
    int flag = 0;   //标志
    Node *p = head->next;                   
    if(p == NULL){
        printf("此链表中无记录!\n ");
        return;
    }  
    printf("\n请输入要修改成绩的学生学号:");
    scanf("%s",&temp);
    while(p != NULL){
         if(strcmp(p->stu.sno,temp) == 0){  //找到就输出信息
             flag = 1; 
             printf("\n-------------------------------------------------------------------------------------\n");
             printf("\n旧的信息为:\n");
            printf("学号:%s\t\t",p->stu.sno);
             printf("姓名:%s\t\t",p->stu.name);
             printf("成绩:%.2f\n",p->stu.grade); 
             
            printf("\n请输入该学生新的成绩:");
            scanf("%f",&p->stu.grade);
            printf("修改成功!\n");  
            writeStuinfo(head);
            break;    
        }else{
            p = p->next;       //没找到往后遍历 
        }        
    }
    if(flag == 0){
        printf("\n不存在该学生信息!\n");
    }
    printf("\n");
}

int main(){
    int choice;
    Node *head = NULL;     //头指针 
    head = createHeadNode();   //创建一个带头结点的空链表 
    readStuinfo(head);      //读取文本的信息  
    while(1){
        Menu();
        printf("请输入选择:");
        scanf("%d",&choice);
        switch(choice){
            case 1:
                addStuinfo(head);
                system("pause");
                system("cls");
                break;
            case 2:
                searchStuinfo(head);
                system("pause");
                system("cls");
                break;
            case 3:
                updateStuinfo(head);
                 system("pause");
                system("cls");
                break;
            case 4:
                displayStuinfo(head);
                system("pause");
                system("cls");
                break;
            case 5:
                displaygradeStuinfo(head);
                 system("pause");
                system("cls");
                break;
            case 6:
                 writeStuinfo(head);
                 system("pause");
                system("cls");
                break;
            case 0:
                printf("退出成功!\n");
                exit(0);
            default:
                printf("输入错误!请重新输入!\n"); 
                system("pause");
                system("cls");
                break;
        }
    } 
    return 0;
} 

  • 10
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值