905853663 发表于 2021-3-4 23:03:06

有关文件

#include<stdio.h>
#include<stdlib.h>
struct student
{
        int num;
        char name;
        float mark;
}student;
void save()
{
        int i;
        FILE *p;
        if ((p=fopen("mark.dat","wb"))==NULL)
           {printf("错误");exit (0);}
        for (i=0;i<3;i++)
          if (fwrite(&student,sizeof (struct student),1,p)!=1)
              printf("错误");
        fclose(p);             
}
void load()
{
        int i;
        FILE *fp;
        if ((fp=fopen("mark.dat","rb"))==NULL)
           {printf("错误");exit (0);}
        for (i=0;i<3;i++)
          fread(&student,sizeof (struct student),1,fp);
        for (i=0;i<3;i++)
          if ((student.mark)>85)
                     printf("第%d个学生成绩高于85,具体是%f\n",i+1,student.mark);
                       
        fclose(fp);               
          
}
void main ()
{
        void save();
        void load();
        int i;
        printf("请输入三个学生的学号,姓名和成绩\n");
        for (i=0;i<3;i++)
           scanf("%d,%s,%f",&student.num,student.name,&student.mark);
        save();
        load();   
}


代码如上,生成的mark.dat文件里面num那部分为什么会转换成ASCII格式?比如定义一个学生编号是101,在文件里显示是e。还有就是load函数哪里有问题吗,怎么打印不出来?请指点!!!

jackz007 发表于 2021-3-4 23:12:30

本帖最后由 jackz007 于 2021-3-4 23:14 编辑

       你这个文件内容是结构体数据,属于二进制内容,不可以用记事本打开看。

905853663 发表于 2021-3-4 23:21:26

jackz007 发表于 2021-3-4 23:12
你这个文件内容是结构体数据,属于二进制内容,不可以用记事本打开看。

这样啊,那为啥名字和成绩可以正常显示呢?那应该用什么打开呢?

jackz007 发表于 2021-3-4 23:36:16

905853663 发表于 2021-3-4 23:21
这样啊,那为啥名字和成绩可以正常显示呢?那应该用什么打开呢?

      二进制数据不是文本,除了字符串成分可以在记事本中直接看到,所有的 int、float 型的数据都是二进制的,必须把它们读入结构体后,按照各个成员的数据类型分别进行相应的显示。例如,printf() 中使用的格式描述符,整型用 "%d",浮点数用 "%f" 等等。

905853663 发表于 2021-3-5 09:36:42

jackz007 发表于 2021-3-4 23:36
二进制数据不是文本,除了字符串成分可以在记事本中直接看到,所有的 int、float 型的数据都是二进 ...

是的,那个load就是实现这个的,但是打印不出来,不知程序哪里错了

jackz007 发表于 2021-3-5 09:45:27

本帖最后由 jackz007 于 2021-3-5 09:46 编辑

      打印得有人的分数大于 85 才行,请给出你的样例,就是键盘输入及屏幕显示内容。

905853663 发表于 2021-3-5 11:15:24

jackz007 发表于 2021-3-5 09:45
打印得有人的分数大于 85 才行,请给出你的样例,就是键盘输入及屏幕显示内容。

file:///C:/Users/CJL/Pictures/Screenshots/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE(13).png

905853663 发表于 2021-3-5 11:17:08

jackz007 发表于 2021-3-5 09:45
打印得有人的分数大于 85 才行,请给出你的样例,就是键盘输入及屏幕显示内容。

发不了图片,就是键盘输入这个:101,dggd,74
                                                102,dfa,86
                                                 103,sesr,100
然后按回车,屏幕没有输出

jackz007 发表于 2021-3-5 11:41:59

905853663 发表于 2021-3-5 11:17
发不了图片,就是键盘输入这个:101,dggd,74
                                                102, ...

       问题出在这里
         scanf("%d,%s,%f",&student.num,student.name,&student.mark);
      name + mark 被当作了 name,结果,所有的 mark 值为 0
      这样改
         scanf("%d%s%f",&student.num,student.name,&student.mark);
      输入的时候,把作为分隔符的逗号去掉。

905853663 发表于 2021-3-5 11:49:40

jackz007 发表于 2021-3-5 11:41
问题出在这里

      name + mark 被当作了 name,结果,所有的 mark 值为 0


确实是这个!谢谢!!但是为啥会这样呢,加了逗号只是起到分隔符的作用不是吗

jackz007 发表于 2021-3-5 11:58:34

905853663 发表于 2021-3-5 11:49
确实是这个!谢谢!!但是为啥会这样呢,加了逗号只是起到分隔符的作用不是吗

      有一句衷告,scanf() 的格式描述符字符串中最好不要包含任何非必须的内容,越简洁越好。

905853663 发表于 2021-3-5 11:59:14

jackz007 发表于 2021-3-5 11:58
有一句衷告,scanf() 的格式描述符字符串中最好不要包含任何非必须的内容,越简洁越好。

这样啊

905853663 发表于 2021-3-5 12:21:25

jackz007 发表于 2021-3-5 11:58
有一句衷告,scanf() 的格式描述符字符串中最好不要包含任何非必须的内容,越简洁越好。

那请问执行了save函数后,内存里还存储了这个结构体的吗,还是说写进磁盘文件里面后内存就释放了?

jackz007 发表于 2021-3-5 12:28:00

本帖最后由 jackz007 于 2021-3-5 12:29 编辑

905853663 发表于 2021-3-5 12:21
那请问执行了save函数后,内存里还存储了这个结构体的吗,还是说写进磁盘文件里面后内存就释放了?

   本例中的结构体数组是全局变量,从程序启动到退出期间都始终存在,在程序的整个生命周期内,这块内存一定不会释放。其内容取决于输入,第一次是从键盘输入中获取,第二次是从磁盘文件中获取,除非你修改,否则,电脑是不会 "擅自做主" 帮你修改的。

905853663 发表于 2021-3-5 12:40:50

jackz007 发表于 2021-3-5 12:28
本例中的结构体数组是全局变量,从程序启动到退出期间都始终存在,在程序的整个生命周期内,这块 ...

噢噢懂了,如果不是全局变量呢?

jackz007 发表于 2021-3-5 12:46:51

本帖最后由 jackz007 于 2021-3-5 12:49 编辑

905853663 发表于 2021-3-5 12:40
噢噢懂了,如果不是全局变量呢?

      如果不是全局变量,那就得在函数中进行声明,其生命周期为函数被调用期间,函数未被调用或调用结束时,作为局部变量的结构体数组在物理上就根本不存在。所以,任何时候都不要试图从函数外部去访问一个函数的局部变量。

红了眼 发表于 2021-3-5 12:54:32

jackz007 发表于 2021-3-5 12:46
如果不是全局变量,那就得在函数中进行声明,其生命周期为函数被调用期间,函数未被调用或调用 ...

晓得了
页: [1]
查看完整版本: 有关文件