为什么 fread() 没有得到预期的字节数?
Why fread() is not getting the expected bytes?
我正在尝试使用 C 以二进制模式读取文件,但它仅将前 43 个字符存储在缓冲区中。
我想以 245 字节为一组读取文件。它包含多字符字节和空字符。
这是文件的十六进制内容:
323031353037303735393036333130343739332032373231333732534e30323033323545533036303130340000000008557c0000000000693c0000000000000c0000000008557c0000000000693c0000000000000c0000000008557c0000000000693c0000000000000c00001c00001c00001c00000c00000c00000c00001c4d4e202020204942202020204f393920202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202039444b524d4144
这是我的代码:
char* to_hex(const char* strin) {
char * strout = malloc(2 * strlen(strin) + 1);
int x;
for (x = 0; x < strlen(strin);x++){
sprintf(&strout[x+x],"%02x", (int)(*(unsigned char*)(&strin[x])) );
}
strout[2 * strlen(strin)]='[=11=]'
return strout;
}
int main(int argc, char *argv[]) {
FILE * pfinput = fopen("stack.bin", "rb");
int lrec = 245;
char* sbuff = (char *)malloc((lrec + 1) * sizeof(char));
if (pfinput != NULL) {
while (fread (sbuff, 1, lrec, pfinput) > 0){
sbuff[lrec] = '[=11=]';
printf("len=%d hex=%s\n\n", strlen(sbuff), to_hex(sbuff) );
}
}
return 0;
}
它returns以下内容:
len=43 hex=323031353037303735393036333130343739332032373231333732534e3032303332354553303630313034
Why it only reads 43 characters instead of 245?
Do you have any alternative to do it?
当您的字符串中嵌入了空字符时,您无法使用 strlen
来可靠地计算字符数。需要抓取fread
读取的字符数,使用
int nread = 0;
while (( nread = fread (sbuff, 1, lrec, pfinput)) > 0)
而不是
printf("len=%d hex=%s\n\n", strlen(sbuff), to_hex(sbuff) );
您需要使用:
printf("len=%d hex=%s\n\n", nread, to_hex(sbuff) );
您还需要将 nread
传递给 to_hex
,以便您能够在该函数中适当地处理嵌入的空字符。
char* to_hex(const char* strin, int nread) {
char * strout = malloc(2 * nread + 1);
int x;
for (x = 0; x < nread; x++){
sprintf(&strout[x+x],"%02x", (int)(*(unsigned char*)(&strin[x])) );
}
strout[2 * nread]='[=13=]';
return strout;
}
之后,printf
行需要是:
printf("len=%d hex=%s\n\n", nread, to_hex(sbuff, nread) );
PS 注意这里是内存泄漏。由 to_hex
分配的内存用于调用 printf
但之后它不会被释放。您可能希望在变量中捕获该内存并释放它。
char* hexstring = to_hex(sbuff, nread);
printf("len=%d hex=%s\n\n", nread, hexstring);
free(hexstring);
此外,在从 main
返回之前释放 sbuff
。
free(sbuff);
PS 2 我会简化行
sprintf(&strout[x+x],"%02x", (int)(*(unsigned char*)(&strin[x])) );
至
int c = strin[x];
sprintf(&strout[x+x],"%02x", c );
'Upon successful completion, fread() shall return the number of elements successfully read',
fread() 返回的值是确定已将多少字节读入缓冲区的唯一方法。在文件末尾,可能会读取少于 'lrec' 个字符。
我正在尝试使用 C 以二进制模式读取文件,但它仅将前 43 个字符存储在缓冲区中。 我想以 245 字节为一组读取文件。它包含多字符字节和空字符。 这是文件的十六进制内容:
323031353037303735393036333130343739332032373231333732534e30323033323545533036303130340000000008557c0000000000693c0000000000000c0000000008557c0000000000693c0000000000000c0000000008557c0000000000693c0000000000000c00001c00001c00001c00000c00000c00000c00001c4d4e202020204942202020204f393920202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202039444b524d4144
这是我的代码:
char* to_hex(const char* strin) {
char * strout = malloc(2 * strlen(strin) + 1);
int x;
for (x = 0; x < strlen(strin);x++){
sprintf(&strout[x+x],"%02x", (int)(*(unsigned char*)(&strin[x])) );
}
strout[2 * strlen(strin)]='[=11=]'
return strout;
}
int main(int argc, char *argv[]) {
FILE * pfinput = fopen("stack.bin", "rb");
int lrec = 245;
char* sbuff = (char *)malloc((lrec + 1) * sizeof(char));
if (pfinput != NULL) {
while (fread (sbuff, 1, lrec, pfinput) > 0){
sbuff[lrec] = '[=11=]';
printf("len=%d hex=%s\n\n", strlen(sbuff), to_hex(sbuff) );
}
}
return 0;
}
它returns以下内容:
len=43 hex=323031353037303735393036333130343739332032373231333732534e3032303332354553303630313034
Why it only reads 43 characters instead of 245?
Do you have any alternative to do it?
当您的字符串中嵌入了空字符时,您无法使用 strlen
来可靠地计算字符数。需要抓取fread
读取的字符数,使用
int nread = 0;
while (( nread = fread (sbuff, 1, lrec, pfinput)) > 0)
而不是
printf("len=%d hex=%s\n\n", strlen(sbuff), to_hex(sbuff) );
您需要使用:
printf("len=%d hex=%s\n\n", nread, to_hex(sbuff) );
您还需要将 nread
传递给 to_hex
,以便您能够在该函数中适当地处理嵌入的空字符。
char* to_hex(const char* strin, int nread) {
char * strout = malloc(2 * nread + 1);
int x;
for (x = 0; x < nread; x++){
sprintf(&strout[x+x],"%02x", (int)(*(unsigned char*)(&strin[x])) );
}
strout[2 * nread]='[=13=]';
return strout;
}
之后,printf
行需要是:
printf("len=%d hex=%s\n\n", nread, to_hex(sbuff, nread) );
PS 注意这里是内存泄漏。由 to_hex
分配的内存用于调用 printf
但之后它不会被释放。您可能希望在变量中捕获该内存并释放它。
char* hexstring = to_hex(sbuff, nread);
printf("len=%d hex=%s\n\n", nread, hexstring);
free(hexstring);
此外,在从 main
返回之前释放 sbuff
。
free(sbuff);
PS 2 我会简化行
sprintf(&strout[x+x],"%02x", (int)(*(unsigned char*)(&strin[x])) );
至
int c = strin[x];
sprintf(&strout[x+x],"%02x", c );
'Upon successful completion, fread() shall return the number of elements successfully read',
fread() 返回的值是确定已将多少字节读入缓冲区的唯一方法。在文件末尾,可能会读取少于 'lrec' 个字符。