读取文件内容时,被判定为EOF?

幻夢之葉 2017-11-02 06:11:50
文件内有那么一段内容(十六进制)
... 001A 0500 0000 ...

我用FILE对红色部分读取(4字节)时候,被判定为文件结束?

对此,我写了个测试程序进行验证,依旧如此,是VS下FILE设计的本意 还是我本地的Bug?

下面是我的测试程序(我此处把1306替换为其他,就读取正常)

#include <cstdio>
#include <cstring>

int main()
{
FILE *fp = fopen("E:\\111.txt", "w");
if (!fp)
{
printf("Save failed.");
return 0;
}

int val = 1306;
unsigned char buf[6] = { 0 };
memcpy(&buf[1], &val, sizeof(int));
fwrite(buf, sizeof(char), 6, fp);
fclose(fp);

fp = fopen("E:\\111.txt", "r");
if (!fp)
{
printf("Open failed.");
return 0;
}

char c = 0;
int rval = 0;
int ret1 = fread(&c, 1, 1, fp);
int ret2 = fread(&rval, 4, 1, fp);

printf("%d %d %d %d\n", ret1, ret2, feof(fp) ? 1 : 0, ferror(fp) ? 1 : 0);
printf("%d %d\n", c, rval);

fclose(fp);

return 0;
}
...全文
491 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
eeeeelin 2017-11-13
  • 打赏
  • 举报
回复
受教了,都是大神
赵4老师 2017-11-06
  • 打赏
  • 举报
回复
不要把 fopen("...","...");fscanf,fprintf,fgets,fgetc,fclose //读时把\r\n替换成\n,写时把\n替换成\r\n;读到\x1a就设置EOF;读写的内容当字符看待 和 fopen("...","...b");fseek,ftell,fread,fwrite,fgetc,fclose //不作以上替换,遇到\x1a仍继续读;读写的内容当字节看待 弄混了
paschen 版主 2017-11-04
  • 打赏
  • 举报
回复
引用 5楼自信男孩 的回复:
[quote=引用 1 楼 paschen 的回复:] 你文件是用文本方式打开,读的时候却是按二进制读,你重新按二进制方式打开文件再读即可
我感觉跟这个打开方式没关系,只要是fwrite写入的,用fread读应该没问题;[/quote]所以用文本方式打开按二进制读取行为未定义,你可以跟踪进fread代码分析原因
paschen 版主 2017-11-03
  • 打赏
  • 举报
回复
引用 2 楼 幻夢之葉的回复:
[quote=引用 1 楼 paschen 的回复:]
你文件是用文本方式打开,读的时候却是按二进制读,你重新按二进制方式打开文件再读即可

感谢提醒。不记得我工程里面怎么使用了,明天我看看。
最近老是犯低级错误,忧伤![/quote]
fp = fopen("s:\\111.txt", "r"); 改成 fp = fopen("s:\\111.txt", "rb");
幻夢之葉 2017-11-03
  • 打赏
  • 举报
回复
引用 1 楼 paschen 的回复:
你文件是用文本方式打开,读的时候却是按二进制读,你重新按二进制方式打开文件再读即可
感谢提醒。不记得我工程里面怎么使用了,明天我看看。 最近老是犯低级错误,忧伤!
自信男孩 2017-11-03
  • 打赏
  • 举报
回复
我在Linux下测试了你的程序,没做任何修改;输出的结果是:

1  1  0 0
0  1306
说明读的时候并没有到文件末尾,因为写的时候其实是写了6个字节,但是读的时候读了5个字节,所以不到文件末尾; 当读第7个字节时,此时就会提示EOF 稍微修改的代码如下:
#include <iostream>
#include <cstdio>
#include <cstring>

int main()
{
    FILE *fp = fopen("111.txt", "w");
    if (!fp)
    {
        printf("Save failed.");
        return 0;
    }

    int val = 1306;
    unsigned char buf[6] = { 0 };
    memcpy(&buf[1], &val, sizeof(int));
    fwrite(buf, sizeof(char), 6, fp);
    fclose(fp);

    fp = fopen("111.txt", "r");
    if (!fp)
    {
        printf("Open failed.");
        return 0;
    }

    char c = 0, c1 = 0, c2 = 0;
    int rval = 0;
    int ret1 = fread(&c, 1, 1, fp);
    int ret2 = fread(&rval, 4, 1, fp);
    int ret3 = fread(&c1, 1, 1, fp);
    int ret4 = fread(&c2, 1, 1, fp);

    printf("%d %d %d %d %d %d\n", ret1, ret2, ret3, ret4, feof(fp) ? 1 : 0, ferror(fp) ? 1 : 0);
    printf("%d %d %d\n", c, c1, rval);

    fclose(fp);

    return 0;
}
结果如下:

1 1 1 0 1 0
0 0 1306
因为我是在Linux下操作的,所以结果仅供参考~
自信男孩 2017-11-03
  • 打赏
  • 举报
回复
引用 1 楼 paschen 的回复:
你文件是用文本方式打开,读的时候却是按二进制读,你重新按二进制方式打开文件再读即可
我感觉跟这个打开方式没关系,只要是fwrite写入的,用fread读应该没问题;
幻夢之葉 2017-11-03
  • 打赏
  • 举报
回复
引用 3 楼 paschen 的回复:
[quote=引用 2 楼 幻夢之葉的回复:][quote=引用 1 楼 paschen 的回复:] 你文件是用文本方式打开,读的时候却是按二进制读,你重新按二进制方式打开文件再读即可
感谢提醒。不记得我工程里面怎么使用了,明天我看看。 最近老是犯低级错误,忧伤![/quote] fp = fopen("s:\\111.txt", "r"); 改成 fp = fopen("s:\\111.txt", "rb");[/quote] 明白的,我说的工程是指在我的项目不是这里的代码 =。=
paschen 版主 2017-11-02
  • 打赏
  • 举报
回复
你文件是用文本方式打开,读的时候却是按二进制读,你重新按二进制方式打开文件再读即可

64,654

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧