我正在尝试读取从命令行参数解析的文件,每次 16 个字节。我将字节存储在一个无符号字符数组中。然后,我尝试以 HEX 格式打印元素,然后,如果它们是可打印字符,则打印它们,如果不是,则打印一个点“。”我还想在每个新行上打印文件开头的字节偏移量,但我想在开始处理之前让其余部分工作。我遇到的问题是我正在读取的文件没有打印,所以我认为我做得不对。我开始使用 fread()
但我想我可能需要使用 fseek()
但我不确定。如果有人能指出我正确的方向或告诉我我是否做错了什么,我将不胜感激。
代码:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
FILE *fp;
int i, j;
unsigned char buffer[17];
fp = fopen(argv[1], "r");
while(!feof(fp))
{
while(fread(buffer, 16, 1, fp) !=0)
{
for(i=0; i < 16; i++)
{
printf("%X ", buffer[i]);
}
for(j = 0; j < 16; j++)
{
if(isprint(buffer[j]))
printf("%s", buffer[j]);
else
printf("." );
}
printf("\n");
}
}
fclose(fp);
return 0;
}
预期输出:
0001: 40 4F 28 37 0B B8 FF 9D 81 5E 2E 73 B5 CC 6A 70 @O(7.....^.s..jp
0010: 0F 30 9C 6E 7E F7 53 E0 C1 5E 9A 38 C5 02 F2 33 .0.n .S..^.8...3
编辑:修复了建议问题。以文本模式而不是二进制模式打开文件。将读取模式更改为
"rb"
并且代码现在可以正常工作。
最佳答案
您需要以二进制模式打开文件,在文本模式下对文件使用 fseek/ftell 会给出不稳定的值。
所以打开文件
fp = fopen(argv[1], "rb");
同样好的做法是始终通过检查返回值来检查函数是否成功,在这种情况下
if (fp != NULL) ...
而不是读取 16 字节块读取 1 字节 16 次,否则如果文件长度不能被 16 整除,你会错过最后一个字节
if ( fp != NULL )
{
int read = 0;
while((read = fread(buffer, 1, 16, fp)) > 0)
{
for(i=0; i < read; i++)
{
...
}
fclose(fp);
}
IOW 无需为外层
while (feof(fp)) ...
在
printf("%s", buffer[j]);
您没有使用正确的格式说明符,buffer[j] 是一个字符,而不是一个字符串,所以写
printf("%c", buffer[j]);
编辑:如果您不在某些嵌入式环境中,一次读取 16 个字节的最小堆栈不是那么有效,您可以读取 2k 或更大的大小以更快地读取。
关于c - 在 C 中一次读取 16 个字节的文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26412611/