读取 N 个字节时害怕意外行为

fread unexpected behaviour when reading N bytes

我正在尝试一次读取四个字节的二进制文件。我想出了这段产生预期输出的代码:

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

int main() {
    char instr[4];
    FILE *fp;

    fp = fopen("tests", "rb");

    while( fread(instr, 1, 4, fp) != 0 ) {
        printf("%td", strlen(instr));
    }

    printf("\n");
}

输出

$ ./bin_files
44444

另一方面,这个修改后的版本产生了一个我无法解释的输出:

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

int main() {
    int i = 10;
    char instr[4];
    FILE *fp;

    fp = fopen("tests", "rb");

    printf("%d\n", i);

    while( fread(instr, 1, 4, fp) != 0 ) {
        printf("%td", strlen(instr));
    }

    printf("\n");
}

输出

$ ./bin_files
10
55555

为什么现在一次读取 5 个字节?

注意:我使用的是 Macbook,这就是为什么我使用 %td 而不是 %d 来打印字符串长度的原因。

strlen 需要一个指向字符串的指针作为参数,但 fread 不会空终止其缓冲区。使用累加的freadreturn值得到读取的大小

此外,使用 %zu 转换规范来打印 size_t 值(由 strlen 编辑的值 return 的类型)。 %tu 用于 ptrdiff_t 类型。

fread 不会在数组末尾添加 NUL 字符 ('[=12=]')。你拥有的不是字符串 .

strlen需要一个字符串形式的参数,字符串的长度由终止NUL字符决定。所以这样的行为。

您可以在数组中手动​​添加一个 NUL 字符,使其成为一个字符串。

还有 strlen returns 类型 size_t 的长度,因此使用 %zu 说明符打印它。