C语言 为什么fread()函数读取,然后光标跳转到随机位置?

vpfxa7rd  于 12个月前  发布在  其他
关注(0)|答案(2)|浏览(169)

我尝试使用fread()从文件中读取二进制数据,但在阅读后,文件的当前位置以某种方式取决于我正在阅读的文件。
我用不同的输入文件运行这个简单的代码:

#include <stdio.h>

int main(int argc, char** argv) {
    FILE* in = fopen(argv[1], "r");
    char buff[10];
    fseek(in, 0, SEEK_SET);
    fread(buff, sizeof(char), 10, in);
    printf("Final position: %d\n", (int)ftell(in));
    return 0;
}

字符串
控制台(我在Windows上运行它,来自MinGW的g ++. exe编译器):

$ ./p.exe test_data/test_elf
Final position: 692
$ ./p.exe test_data/test.cc
Final position: 11
$ ./p.exe example.txt 
Final position: 9


我希望最后的位置是10,因为我们从0开始读取10个字节,我错在哪里?

更新

以下是文件内容:

$ hexdump example.txt 
0000000 3231 3433 3635 3837 3039 6261 6463 6665
0000010 6867 6a69 6c6b 6f6e 7170 7372 7574 7776
0000020 7978 207a 2320 2524 265e 282a e229 9684
0000030 253b 3f3a 282a 7b29 5b7d 0a5d
000003c

$ hexdump test_data/test.cc
0000000 0a0d 7361 286d 6e22 706f 2922 0d3b 610a
0000010 6d73 2228 756c 2069 3278 202c 7830 3031
0000020 2230 3b29 2020 2020 2020 2020 2020 2020
0000030 2020 2f2f 5320 2050 6573 2074 6f74 3120
... (more)

$ hexdump test_data/test_elf
0000000 457f 464c 0101 0001 0000 0000 0000 0000
0000010 0002 00f3 0001 0000 0074 0001 0034 0000
0000020 0334 0000 0000 0000 0034 0020 0002 0028
0000030 0008 0007 0001 0000 0000 0000 0000 0001
... (more)

yzuktlbb

yzuktlbb1#

@mozhayaka我想,你最好使用"rb"模式而不是"r"。当你在文本模式"r"下打开一个文件时,在某些系统上,文件中的换行符'\n'会自动转换为该系统相应的新行序列。
所以将fopen行改为:

FILE* in = fopen(argv[1], "rb");

字符串
希望能对您有所帮助。

r6vfmomb

r6vfmomb2#

对于以文本模式打开的流,ftell()返回的数字不一定是从文件开始的偏移量(以字节为单位),因为行尾转换和遗留系统上的其他潜在转换。在unix系统上,或者如果使用"rb"以二进制模式打开文件,则所有运行(或更少,如果文件更短)都应该获得10
还要注意这些问题:

  • 你不检查fopen故障
  • 不打印fread的返回值

试试这个修改版本:

#include <errno.h>
#include <stdio.h>
#include <string.h>

int main(int argc, char *argv[]) {
    if (argc < 2) {
        fprintf(stderr, "missing argument\n");
        return 1;
    }
    FILE *in = fopen(argv[1], "rb");
    if (in == NULL) {
        fprintf(stderr, "cannot open %s: %s\n", argv[1], strerror(errno));
        return 1;
    }
    char buff[10];
    fseek(in, 0, SEEK_SET);  // actually useless
    size_t nread = fread(buff, sizeof(char), 10, in);
    printf("Read %zu bytes, final position: %ld\n", nread, ftell(in));
    fclose(in);
    return 0;
}

字符串

相关问题