| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 4198 人关注过本帖
标题:C语言:将运行无误的键盘输入数据的程序改写成文件输入并保存,如何从同一个 ...
只看楼主 加入收藏
liuyutong889
Rank: 1
等 级:新手上路
帖 子:4
专家分:0
注 册:2014-11-25
结帖率:100%
收藏
已结贴  问题点数:20 回复次数:6 
C语言:将运行无误的键盘输入数据的程序改写成文件输入并保存,如何从同一个文件向两个 struct 输入
声明:1我的键盘输入数据进行操作的肯定没错的,要添加的只有一个load函数(从某个text里输入数据),和保存在另一个文件用的save函数
 2由于百度知道没法穿文件,所以我只能拍个图,如果有意愿的大神私信或者啥的留个什么方式,我把代码传过去这样改着方便。
3我大概知道怎么改,用fread(&stu[i],sizeof(struct student),1,fp),可是我这个程序里用了两个struct结构,不知道怎么从一个文件顺序地给两个strcut输入,fread(&cou[i],sizeof(struct cou),1,fp)的话不是和第一个fread一样都从头读了嘛。。。
4觉得可能用到fseek吧。。。
5啰啰嗦嗦说了好多,其实就是希望大神帮忙,自学不容易啊,input sort啥的可以忽略,我就是搞不懂怎么输入输出,只要改动不大,实现输入数据和另外保存就好。
输入数据的格式大概:一开始四门课程名字 之后是结构体stu[]的数据

我的原来键盘输入和我自己改的都发上来好了(我自己改的总说打不开文件= =)
改的:
#include<stdio.h>
#include<stdlib.h>
#include<process.h>
#define H 6//预处理宏定义命令(定义一个宏),预处理:在程序编译前先进行替换,将所有H替换为6;
//另外在C语言里宏定义只用来做的宏名替换,而不做语法检查的,因而它不是C语句,所以在宏定义的时候不需要在后面加";"
//便于更普遍的学生成绩排名的应用
#define L 4//所有L替换为4,同理H
struct course// (自学第9章内容后)声明一个结构体类型struct course
//选择struct,放弃数组是因为:学生成绩、对应课程等的一些联系紧密,结构较数组清晰
//在main函数里声明其他函数要想调用需要首先调用main函数,但是在main函数外面声明的函数调用是可直接调用
//所以在本上机作业中,为了在四个函数中都直接调用,采用在main函数外部声明
{
 char name[L][50];//成员name为字符串,代表L门课程的名称
 
}cou;//定义course结构体变量cou
struct student// 声明一个结构体类型struct student
{  
  char name[10];//成员name为字符串,代表学生姓名
  int score[L];//成员score为整型,代表L门课程的成绩
  float  ave;//成员ave为浮点型,代表某个学生的平均成绩
  int max,min,maxid,minid,maxnum,minnum;// 最大、最小以及它们的次序
  // int order;//名次
}stu[H];//定义student结构体下的数组stu
FILE*fp;
void input()//定义input函数,功能:累积总成绩求均分+比较最高最低记录ID
//先声名了函数input、sort、show,所以在之后的main函数中不用再声明
{
  int i,j;
  float sum=0.0;//总分
  for(i=0;i<H;i++)
    {
      sum+=stu[i].score[j];//每次循环同时累加L门课程总分
      if(j==0)
        {
          stu[i].max=stu[i].score[0];//max是结构体数组stu[]中的成员,代表最高分;
          stu[i].maxid=0;//正如命名ID仅仅用于后面打印最高最低分对应课程名称的指示,如:cou.name[(stu[i].maxid)]
          stu[i].min=stu[i].score[0];//j=0时,将学生第一门的成绩赋予最大和最小,初始化
          stu[i].maxid=0;//j=o时,将学生的最高最低成绩ID初始化=0
        }
      if(stu[i].score[j]<stu[i].min)//以最小的基准,比较某名学生成绩(如果某门成绩<之前比较得出的最小的成绩)
      {
          stu[i].min=stu[i].score[j];//当满足比累计的最小值还小时,将此成绩替换给最小值
          stu[i].minid=j;//记录当前最小值的次序
        }
      
      if(stu[i].max<stu[i].score[j])//同理以最小为基准的比较操作(如果某门成绩》之前比较得出的最大的成绩)
        {
          stu[i].max=stu[i].score[j];
          stu[i].maxid=j;
        }
    }
      stu[i].ave=sum/L;//求平均分数
      sum=0;//为下一名学生累计总分清零
}
void sort()//定义函数sort,调整顺序+最高最低的排名,将排名第一的(一整行)放在上面,所以输出排名时候输出的直接是i+1
{
  int i,j;
  struct student ch;//定义结构体数组ch,它和stu有同样的成员,作为替换过程中的中间变量使用
  for(i=0;i<H;i++)
    { stu[i].maxnum=1;//初始化最大最小值的排名
    stu[i].minnum=H;
      for(j=0;j<H;j++)
      {
          if(stu[i].score[(stu[i].maxid)]<stu[j].score[(stu[i].maxid)])
              stu[i].maxnum++;
           if(stu[i].score[(stu[i].minid)]>stu[j].score[(stu[i].minid)])
              stu[i].minnum--;
      }
  }
  for(i=0;i<H;i++)//不要企图用i.j.k一个嵌套的大的for循环实现如结果所示的总排名上的顺序调整以及最高最低的正确排名。
      //因为j,k的比较方式不同,“行变换”会导致混乱。
  {
  for(j=i+1;j<H;j++)//每次和后面的学生平均分比较
    {
      if(stu[i].ave<stu[j].ave)
        {
          ch=stu[i];//若满足要求,则将结构体数组中的整行互换,达到排序作用
          stu[i]=stu[j];
          stu[j]=ch;
        }
    }
}
}
void show()//定义函数show,功能:按要求和顺序打印
{
  int i;
  for(i=0;i<H;i++)
    {printf("\n");//细节:与输入部分分开
     printf("姓名:%s\t均分:%5.2f\t总排名:%d\n最高分:%d\t最高分排名:%d\t课程名称:%s\n最低分:%d\t最低分排名:%d\t课程名称:%s\n\n",stu[i].name,stu[i].ave,i+1,stu[i].max,stu[i].maxnum,cou.name[(stu[i].maxid)],stu[i].min,stu[i].minnum,cou.name[(stu[i].minid)]);    }//打印的平均分是浮点型,且要求共5位长度,小数位为2;由于原始成绩无小数点,所以打印整型;它们以一个tab间距隔开
     printf("\n");//细节:与press any key to continue分开
}
void save()
{
int i;
if((fp=fopen("G:\\上机\\上机1\\stu2.text","wb"))==NULL)////初始化文件指针fp同时判断fp是否是为打开了一个并不存在的文件,fopen带回的空指针
//打开文件名为stu1的文本text;二进制文件,wb:只写
{
 printf("打不开文件\n");
 exit(0);//关闭所有文件,终止正在运行程序,待用户检查错误
}
for(i=0;i<H;i++)//循环存储
if(fwrite(&stu[i],sizeof(struct student),1,fp)!=1)//判断fread()函数有没有操作成功
printf("文件书写错误\n");
fclose(fp);
}
void load()
{
int i;
if((fp=fopen("G:\\上机\\上机1\\stu1.text","rb"))==NULL)//初始化文件指针fp同时判断fp是否是为打开了一个并不存在的文件,fopen带回的空指针
//打开文件名为stu1的文本text;二进制文件,rb:只读
{
 printf("打不开文件\n");
 exit(0);//关闭所有文件,终止正在运行程序,待用户检查错误
}
for(i=0;i<L;i++)
fscanf(fp,"%s",&cou.name[i]);
fseek(fp,sizeof(struct course),0);
for(i=0;i<H;i++)
{
if(fread(&stu[i],sizeof(struct student),1,fp)!=1)//判断fread()函数有没有操作成功
{
    if(feof(fp))//feof()是文件结束检测函数,如果没有结束,返回值是0,结束了是1
{
fclose(fp);
exit;
}//关闭所有文件,终止正在运行程序,待用户检查错误
printf("文件读取错误\n");
}
fclose(fp);
}

for(i=0;i<H;i++)//循环读取
if(fread(&stu[i],sizeof(struct student),1,fp)!=1)//判断fread()函数有没有操作成功
{
    if(feof(fp))//feof()是文件结束检测函数,如果没有结束,返回值是0,结束了是1
{
fclose(fp);
exit(0);
}//关闭所有文件,终止正在运行程序,待用户检查错误
printf("文件读取错误\n");
}
fclose(fp);
}
int main()
{
  load();
  input();
  sort();
  show();
  save();
  return 0;
}

这个是运行无误键盘输入
#include<stdio.h>
#define H 6
#define L 4//所有L替换为4,同理H
struct course// (自学第9章内容后)声明一个结构体类型struct course
{
 char name[L][50];//成员name为字符串,代表L门课程的名称
 
}cou;//定义course结构体变量cou
struct student// 声明一个结构体类型struct student
{
  int score[L];//成员score为整型,代表L门课程的成绩
  char name[10];//成员name为字符串,代表学生姓名
  float  ave;//成员ave为浮点型,代表某个学生的平均成绩
  int max,min,maxid,minid,maxnum,minnum;// 最大、最小以及它们的次序
  // int order;//名次
}stu[H];//定义student结构体下的数组stu
void input()//定义input函数,功能:输入数据+累积总成绩求均分+比较最高最低记录ID
//先声名了函数input、sort、show,所以在之后的main函数中不用再声明
{
  printf("请输入%d门课程的名称\n",L);                                       
  int i,j;
  float sum=0.0;//总分
  for(i=0;i<L;i++)
    {
      scanf("%s",cou.name[i]);
    }
 
  for(i=0;i<H;i++)//循环输入H个学生的姓名和成绩,
    { printf("请输入第%d名学生姓名:",i+1);//对应每个i(学生),都提示输入姓名
  scanf("%s",stu[i].name);
      for(j=0;j<L;j++)
    {printf("请输入此学生第%d门课程成绩:",j+1);//对应每个j(学生某门成绩),都提示输入成绩
      scanf("%d",&stu[i].score[j]);
      sum+=stu[i].score[j];//每次循环同时累加L门课程总分
      if(j==0)
        {
          stu[i].max=stu[i].score[0];//max是结构体数组stu[]中的成员,代表最高分;
          stu[i].maxid=0;//正如命名ID仅仅用于后面打印最高最低分对应课程名称的指示,如:cou.name[(stu[i].maxid)]
          stu[i].min=stu[i].score[0];//j=0时,将学生第一门的成绩赋予最大和最小,初始化
          stu[i].maxid=0;//j=o时,将学生的最高最低成绩ID初始化=0
        }
      if(stu[i].score[j]<stu[i].min)//以最小的基准,比较某名学生成绩(如果某门成绩<之前比较得出的最小的成绩)
      {
          stu[i].min=stu[i].score[j];//当满足比累计的最小值还小时,将此成绩替换给最小值
          stu[i].minid=j;//记录当前最小值的次序
        }
      
      if(stu[i].max<stu[i].score[j])//同理以最小为基准的比较操作(如果某门成绩》之前比较得出的最大的成绩)
        {
          stu[i].max=stu[i].score[j];
          stu[i].maxid=j;
        }
    }
      stu[i].ave=sum/L;//求平均分数
      sum=0;//为下一名学生累计总分清零
}}
void sort()//定义函数sort,调整顺序+最高最低的排名,将排名第一的(一整行)放在上面,所以输出排名时候输出的直接是i+1
{
  int i,j;
  struct student ch;//定义结构体数组ch,它和stu有同样的成员,作为替换过程中的中间变量使用
  for(i=0;i<H;i++)
    { stu[i].maxnum=1;//初始化最大最小值的排名
    stu[i].minnum=H;
      for(j=0;j<H;j++)
      {
          if(stu[i].score[(stu[i].maxid)]<stu[j].score[(stu[i].maxid)])
              stu[i].maxnum++;
           if(stu[i].score[(stu[i].minid)]>stu[j].score[(stu[i].minid)])
              stu[i].minnum--;
      }
  }
  for(i=0;i<H;i++)//不要企图用i.j.k一个嵌套的大的for循环实现如结果所示的总排名上的顺序调整以及最高最低的正确排名。
      //因为j,k的比较方式不同,“行变换”会导致混乱。
  {
  for(j=i+1;j<H;j++)//每次和后面的学生平均分比较
    {
      if(stu[i].ave<stu[j].ave)
        {
          ch=stu[i];//若满足要求,则将结构体数组中的整行互换,达到排序作用
          stu[i]=stu[j];
          stu[j]=ch;
        }
    }
}
}
void show()//定义函数show,功能:按要求和顺序打印
{
  int i;
  for(i=0;i<H;i++)
    {printf("\n");//细节:与输入部分分开
     printf("姓名:%s\t均分:%5.2f\t总排名:%d\n最高分:%d\t最高分排名:%d\t课程名称:%s\n最低分:%d\t最低分排名:%d\t课程名称:%s\n\n",stu[i].name,stu[i].ave,i+1,stu[i].max,stu[i].maxnum,cou.name[(stu[i].maxid)],stu[i].min,stu[i].minnum,cou.name[(stu[i].minid)]);    }//打印的平均分是浮点型,且要求共5位长度,小数位为2;由于原始成绩无小数点,所以打印整型;它们以一个tab间距隔开
     printf("\n");//细节:与press any key to continue分开
}
int main()
{
  input();
  sort();
  show();
  return 0;
}
搜索更多相关主题的帖子: 百度知道 C语言 键盘 如何 百度知道 C语言 键盘 如何 百度知道 C语言 键盘 如何 
2014-11-25 07:57
wp231957
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:神界
等 级:贵宾
威 望:423
帖 子:13688
专家分:53332
注 册:2012-10-18
收藏
得分:0 
这个从文件输入的想法是没有问题的   建议你一步一步从头做起  不要一口吃胖子

比如: 抛弃这个课题 ,先研究如何从文件中读取数据  再研究如何从文件中读取有规律数据(struct一类的)
                      再研究如何向文件中写数据并保存  再研究如何向文件中写有规律数据(struct一类的)   这些单项研究通之后,再向你这个项目中整合 那就不是个事

DO IT YOURSELF !
2014-11-25 08:33
yahwei
Rank: 7Rank: 7Rank: 7
来 自:湖~
等 级:黑侠
威 望:3
帖 子:145
专家分:644
注 册:2011-11-10
收藏
得分:0 
为什么要从同一个文件输出两次?输出到A,然后将A复制到B不行吗?

[qq]949654600[/qq]
2014-11-25 10:18
liuyutong889
Rank: 1
等 级:新手上路
帖 子:4
专家分:0
注 册:2014-11-25
收藏
得分:0 
回复 2 楼 wp231957
stu3.rar (2.73 KB)
求大神帮忙啊
我现在这里编译已经没错误了,但是感觉文件里的东东没传输一一对应,也可能我不太清楚数据源头的txt文件的格式(怎么把数据块分开)
void load()
{
int i;
if((fp=fopen("G:\\stu1.txt","rb"))==NULL)//初始化文件指针fp同时判断fp是否是为打开了一个并不存在的文件,fopen带回的空指针
//打开文件名为stu1的文本text;二进制文件,rb:只读
{
 printf("打不开文件\n");
 return;//关闭所有文件,终止正在运行程序,待用户检查错误
}
if(fread(&cou,sizeof(struct course),1,fp)!=1)//判断fread()函数有没有操作成功
{if(feof(fp))//feof()是文件结束检测函数,如果没有结束,返回值是0,结束了是1
{fclose(fp);
return;
}
printf("文件读取错误\n");
}
fseek(fp,sizeof(struct course),0);
for(i=0;i<H;i++)
if(fread(&stu[i],sizeof(struct student),1,fp)!=1)//判断fread()函数有没有操作成功
{if(feof(fp))//feof()是文件结束检测函数,如果没有结束,返回值是0,结束了是1
{fclose(fp);
return;
}//关闭所有文件,终止正在运行程序,待用户检查错误
printf("文件读取错误\n");
}
fclose(fp);         
}
2014-11-25 13:09
liuyutong889
Rank: 1
等 级:新手上路
帖 子:4
专家分:0
注 册:2014-11-25
收藏
得分:0 
回复 3 楼 yahwei
主要我已经编译没错了,要是那么着改动太多,求大神帮忙啊
感觉文件里的东东没传输一一对应,也可能我不太清楚数据源头的txt文件的格式(怎么把数据块分开)
void load()
{
int i;
if((fp=fopen("G:\\stu1.txt","rb"))==NULL)//初始化文件指针fp同时判断fp是否是为打开了一个并不存在的文件,fopen带回的空指针
//打开文件名为stu1的文本text;二进制文件,rb:只读
{
printf("打不开文件\n");
return;//关闭所有文件,终止正在运行程序,待用户检查错误
}
if(fread(&cou,sizeof(struct course),1,fp)!=1)//判断fread()函数有没有操作成功
{if(feof(fp))//feof()是文件结束检测函数,如果没有结束,返回值是0,结束了是1
{fclose(fp);
return;
}
printf("文件读取错误\n");
}
fseek(fp,sizeof(struct course),0);
for(i=0;i<H;i++)
if(fread(&stu[i],sizeof(struct student),1,fp)!=1)//判断fread()函数有没有操作成功
{if(feof(fp))//feof()是文件结束检测函数,如果没有结束,返回值是0,结束了是1
{fclose(fp);
return;
}//关闭所有文件,终止正在运行程序,待用户检查错误
printf("文件读取错误\n");
}
fclose(fp);         
}
2014-11-25 13:10
liao06550107
Rank: 7Rank: 7Rank: 7
等 级:黑侠
威 望:2
帖 子:111
专家分:696
注 册:2011-10-2
收藏
得分:20 
程序代码:
void LoadToMemeory(){
    int i;
    FILE * fp = NULL;
    if((fp=fopen("G:\\stu1.txt","rb"))==NULL)//块存储的数据,为二进制文件,所以最好文件名为G:\\stu1.dat,防止人为修改
    {
    printf("打不开文件\n");
    return;
    }
    if(fread(&cou,sizeof(struct course),1,fp)!=1)//块读取数据,需要相应的fwrite()函数写入文件,才可以正确的读取
    {if(feof(fp))
    {fclose(fp);
        return;
    }
    printf("文件读取错误\n");
    }
//    fseek(fp,sizeof(struct course),0); //什么意思,把读指针偏移到1个课程结构之后?没有必要,因为前面读的时候,读指针会自动前进一个课程结构的长度。
    for(i=0;i<H;i++)
    if(fread(&stu[i],sizeof(struct student),1,fp)!=1)
    {if(feof(fp))//feof()
        {
        fclose(fp);
        return;
        }
        printf("文件读取错误\n");
    }
    fclose(fp);
}

void WriteToText(){
    int i;
    FILE * fp = NULL;
    if((fp=fopen("G:\\stu1.txt","wb"))==NULL)
    {
    printf("打不开文件\n");
    return;
    }
    if(fwrite(&cou,sizeof(struct course),1,fp)!=1)
    {
    printf("文件写入错误\n");
    }
    for(i=0;i<H;i++)
    if(fwrite(&stu[i],sizeof(struct student),1,fp)!=1)
    {
        printf("文件写入错误\n");
    }
    fclose(fp);
}

听不同的音乐,看不同的书,游历不同的城市,邂逅不同的人,走的多了,站的高了,自然就看的远了。
2014-11-25 16:32
liuyutong889
Rank: 1
等 级:新手上路
帖 子:4
专家分:0
注 册:2014-11-25
收藏
得分:0 
回复 6 楼 liao06550107
我大概搞明白了,不过我还是不拉么高端修改了别的,不过还是很感谢能得到负责的帮助。毕竟程序一长,回答都敷衍了,不是计算机专业的摸索的很难。
2014-11-25 17:54
快速回复:C语言:将运行无误的键盘输入数据的程序改写成文件输入并保存,如何从 ...
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.039188 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved