读取 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
不会空终止其缓冲区。使用累加的fread
return值得到读取的大小
此外,使用 %zu
转换规范来打印 size_t
值(由 strlen
编辑的值 return 的类型)。 %tu
用于 ptrdiff_t
类型。
fread
不会在数组末尾添加 NUL
字符 ('[=12=]'
)。你拥有的不是字符串 .
而strlen
需要一个字符串形式的参数,字符串的长度由终止NUL
字符决定。所以这样的行为。
您可以在数组中手动添加一个 NUL
字符,使其成为一个字符串。
还有 strlen
returns 类型 size_t
的长度,因此使用 %zu
说明符打印它。
我正在尝试一次读取四个字节的二进制文件。我想出了这段产生预期输出的代码:
#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
不会空终止其缓冲区。使用累加的fread
return值得到读取的大小
此外,使用 %zu
转换规范来打印 size_t
值(由 strlen
编辑的值 return 的类型)。 %tu
用于 ptrdiff_t
类型。
fread
不会在数组末尾添加 NUL
字符 ('[=12=]'
)。你拥有的不是字符串 .
而strlen
需要一个字符串形式的参数,字符串的长度由终止NUL
字符决定。所以这样的行为。
您可以在数组中手动添加一个 NUL
字符,使其成为一个字符串。
还有 strlen
returns 类型 size_t
的长度,因此使用 %zu
说明符打印它。