WY0708 发表于 2021-1-6 12:52:22

C,数据结构

有如下表所示的若干个学生成绩:
学号      姓名      语文      数学      英语      总分      平均
07001      李铭      90      95      80               
07002      张涛      68      75      58               
…      …      …      …      …               
…      …      …      …      …               
要求用C/C++语言编写一个程序将这组学生成绩输入到计算机中,数据的基本存储结构采用结构体数组。
程序要实现的功能如下:
1、      数据查询功能,该功能要求能实现⑴按姓名、学号查询某个学生的所有课程的成绩;⑵按课程能查询某分数段都有哪些学生。
2、      能按上表中横向计算每个学生各门功课的总成绩及平均成绩;纵向计算某门课程的平均分数;
Q:总分和平均成绩不能输出,纵向计算某门课的平均分数算出来是错的?
求解答!

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<conio.h>
#define LEN sizeof(struct student)
//学生信息结构体
struct student
{
      char name;//学生姓名
      char id;//学生学号
      int score;//学生三科成绩
      int sum;
      double average;
      struct student *next;
};

typedef struct student stu;

//声明函数
stu* enter(stu *h);//成绩录入函数
stu* initialize();//初始化链表头函数
void menu();//菜单
void print(stu *h);//成绩打印函数
void statistics(stu *h);//查找统计信息
void search(stu *h);//查找某一段成绩的学生
void aver(stu *h);//每一科的平均成绩
void quit(stu *h);//退出函数
void save(stu *h);//保存文件函数
void open(stu *h);//打开文件读取信息建立链表函数

int count=0;
//主函数
int main()
{
      stu *data;//指向链表头,建立成绩链表,所有学生信息存放 在此链表
      int function;//功能选项
      char flag;//判断变量
      int t=0;

      data=initialize();//初始化头结点
      open(data);//读取文件内的数据,并建立链表
      while(1)
      {
                menu();//打开菜单
                printf("请选择操作:");
                scanf("%d",&function);//输入你想要实现的功能
                switch(function)//构建多个功能分支
                {
                        case 1:while(1)
                        {
                              enter(data);//输入一个数据并连接在链表的后面
                              printf("是否继续输入(y/n)");
                              scanf("%s",&flag);
                              if(flag=='N'||flag=='n')break;
                              else count++;
                        }system("cls");break;
                        case 2:print(data);_getch();system("cls");break;                     
                        case 3:statistics(data);_getch();system("cls");break;
                        case 4:search(data);_getch();system("cls");break;
                        case 5:aver(data);_getch();system("cls");break;
                        case 6:quit(data);break;
                        default:printf("error!!!请重新输入:");
                        break;
                }//switch结束
      }
      return 0;
}

//系统界面显示
void menu()
{
      printf("          ***********************************************             \n");
      printf("            **********学生成绩管理系统*****************               \n");
      printf("          ***********************************************             \n");
      printf("                     1.录入和添加成绩                               \n");
      printf("                     2.输出成绩                                     \n");
      printf("                     3.查找学生信息                                 \n");
      printf("                     4.查找某一成绩段的学生成绩                     \n");
      printf("                     5.每一科的平均成绩                           \n");
      printf("                     6.退出系统并保存                               \n");
      printf("          ***********************************************             \n");
}

//初始化头节点函数
stu* initialize()
{
      stu *head;
      head=(stu*)malloc(LEN);
      if(head==NULL)
      {
                printf("error!");
                exit(1);
      }
      head->next=NULL;//使头结点指针域为空
      return head;
}



//成绩录入
stu* enter(stu *h)
{
      stu *p,*q=h;
      char name,id;
      int chinese, math,english;
      p=(stu*)malloc(LEN);//为学生信息申请节点
      printf("请依次输入学生信息:\n");
      printf("姓名 学号 语文 数学 英语\n");
      scanf("%s %s %d %d %d",name,id,&chinese,&math,&english);

      for(;q->next!=NULL;q=q->next){;}//移动到尾结点

//将输入的内容赋值给链表中的相应位置
      strcpy(p->name,name);
      strcpy(p->id,id);
      p->score=chinese;
      p->score=math;
      p->score=english;//赋值完毕
      //移动指针
      p->next=NULL;
      q->next=p;
      q=p;
      return h;

}


//成绩打印
void print(stu *h)
{

      stu *p=h->next;//从头结点之后的结点开始输出      
      printf("%-15s%-10s%-10s%-10s%-10s\n","学号","姓名","语文","数学","英语","总分","平均");//左对齐的方式输出
      while(p!=NULL)//输出链表的全部内容
      {
                printf("%-15s%-10s%-10d%-10d%-10d\n",p->id,p->name,p->score,p->score,p->score,p->sum,p->average);
                p=p->next;
      }
}


//查询统计
void statistics(stu *h)
{
      while(1)
      {
      int z;//选项变量
      system("cls");//清屏
      printf("请输入查找方式:\n7.按姓名查找\n8.按学号查找\n9.退出\n") ;
      scanf("%d",&z);
      system("cls");
      switch(z)
      {
                case 7:{
                        stu *p=h->next;
                char name,id;
                printf("请输入学生姓名:");
                scanf("%s",name);
               while (p)
            {
                     if(strcmp(p->name,name)==0)//比较姓名
                  {
                        printf("当前学生信息:\n");
                        printf("%-15s%-10s%-10s%-10s%-10s\n","学号","姓名","语文","数学","英语");
                        printf("%-15s%-10s%-10d%-10d%-10d\n",p->id,p->name,p->score,p->score,p->score);
                        break;
                  }
                  else
                  {
                        p=p->next;
                  }
                }//while循环结束
                }system("pause");system("cls");break;
                case 8:{
                        stu *p=h->next;
                char name,id;
                printf("请输入学生学号:");
                scanf("%s",id);
               while (p)
            {
                     if(strcmp(p->id,id)==0)//比较学号
                  {
                        printf("当前学生信息:\n");
                        printf("%-15s%-10s%-10s%-10s%-10s\n","学号","姓名","语文","数学","英语");
                        printf("%-15s%-10s%-10d%-10d%-10d\n",p->id,p->name,p->score,p->score,p->score);
                        break;
                  }
                  else
                  {
                        p=p->next;
                  }
                }//while循环结束
                }system("pause");system("cls");break;
                case 9:goto label1;//跳出双重循环
                default:break;
      }
    }
    label1:printf("已退出\n");
}

//查找某一段成绩中的学生
void search(stu *h) {
      stu *p;
      int s,l,f,k=1;
      printf("(输入提示:语文请输入0\t数学请输入1\t英语请输入2)\n请输入需要查询的科目\n");
      scanf("%d",&f);
      printf("请输入分数上限\n");
      scanf("%d",&s);
      printf("请输入分数下限\n");
      scanf("%d",&l);
    for(int i=0;i<4;i++)
    {
       if(p->score<=s&&p->score>=l){
                     printf("学号\t姓名\t语文\t数学\t英语\t总分\t平均分\n");
                     printf("%s\t%s\t%d\t%d\t%d\t%d\t%d\n", p->id, p->name, p->score, p->score, p->score, p->sum, p->average);
                     printf("\n");
         }                  
         else
                   continue;
    }
}

//每一科的平均成绩
void aver(stu *h){
      stu *p;
      int f,i,j;
      double sum1 = 0.0,sum2 = 0.0,sum3 = 0.0;
      printf("(输入提示:语文平均成绩请输入0\t数学平均成绩请输入1\t英语平均成绩请输入2)\n请输入需要查询的科目\n");
    scanf("%d",&f);
      switch(f){
      case 0:for(i = 0;i < count;i++){
                        sum1 = sum1 + p->score;
                         j++;}
                         printf("语文平均成绩: %0.2f\n",sum1 / count);break;
      case 1:for(i = 0;i <count;i++){
                         sum2 = sum2 + p->score;
                         j++;}
                        printf("数学平均成绩: %0.2f\n",sum2 / count);break;
      case 2:for(i = 0;i < count;i++){
                         sum3 = sum3 + p->score;
                         j++;}
                        printf("英语平均成绩: %0.2f\n",sum3 / count);break;
                }
}

//退出系统
void quit(stu *h)
{
      save(h);//退出时保存信息
      exit(0);
}



//打开文件
void open(stu *h)
{
      stu *p=h;
      stu *q;//临时变量,用于保存从文件中提取的信息
      FILE*file=fopen("./Information.txt","rb");
      if(!file)
      {
                printf("文件打开失败!");
                return ;
      }


      q=(stu*)malloc(LEN);//开辟内存
      fread(q,LEN,1,file);//进入循环前先读取一个结点
      while(!feof(file))//判断是否到达文件结尾,如果没有就进入或继续循环
      //否则,就绕过或结束循环
      {
                //代码执行到这里,说明没有到达文件结尾,本次读取的节点数据有效
                p->next=q;//更新链表数据,把新的节点纳入链表
                p=q;//更新链表数据,把新的节点纳入链表
                q=(stu*)malloc(LEN);//分配内存,准备读取下一个结点
                fread(q,LEN,1,file);//读取下一个结点,执行完此句,返回到while循环入口
      }//while循环结束

      p->next=NULL;//使尾结点指向空,结束链表
      fclose(file);
}


//保存信息到文件中
void save(stu *h)
{
      stu *p=h->next;
      int flag;
      FILE *file=fopen("./information.txt","wb");
      if(!file)
      {
                printf("文件打开失败!");
                return ;
      }
      while (p!=NULL)
      {
                flag=fwrite(p,LEN,1,file);//依次将p所指向的链表中的内容写入到文件中
                if(flag!=1)
                {
                        break;
                }
                p=p->next;
      }
      fclose(file);
}
页: [1]
查看完整版本: C,数据结构