[英]Hexdump text and binary files in C
我正在用C语言编写文本和二进制文件中的十六进制转储代码。 我在文本文件中的输出是正确的,但是当我尝试在二进制文件中执行hexdump时,出现了垃圾。 如果我的代码的哪一部分是错误的,我该如何纠正我的错误,我想向您寻求帮助。 谢谢。
#include <stdio.h>
#define OFFSET 16
main(int argc, char const *argv[])
{
FILE *fp;
char buff[OFFSET];
int read;
int address = 0;
int i;
if (argc != 2){
exit(0);
}
fp = fopen(argv[1], "rb");
while ((read = fread(buff, 1, sizeof buff, fp)) > 0){
printf("%08x ", address);
address += OFFSET;
//print hex values
for (i = 0; i < OFFSET; i++){
if(i >= read){
buff[i] = 0;
}
if(buff[i] >= 33 && buff[i] <= 255 || buff[i] != 00){
printf("%02x ", buff[i]);
}
if(buff[i] == 00){
printf(" ");
}
}
//print ascii values
for (i = 0; i < OFFSET; i++) {
printf("%c", (buff[i] >= 33 && buff[i] <= 255 ? buff[i] : ' '));
}
printf("\n");
}
fclose(fp);
}
您在逻辑上有两个错误。 首先,如注释中所指定,二进制文件中的所有字符都同等重要。 不需要(也不应该if(buff[i] >= 33 && buff[i] <= 255 || buff[i] != 00)
对二进制输出测试if(buff[i] >= 33 && buff[i] <= 255 || buff[i] != 00)
。
main
的正确声明是int main (void)
和int main (int argc, char **argv)
(您将看到使用等效的char *argv[]
编写)。 请参阅: C11标准§5.1.2.2.1程序启动p1(草稿n1570) 。 另请参见: 请参见main()在C和C ++中应该返回什么?
接下来是二进制输出,您尝试使用%02x
打印无符号值,但是您正在传递带符号的字符。 如果char
值为负,则您尝试输出带符号扩展值,并输出无符号值的完整宽度( 02x
会将字段填充为2个字符,但不会阻止打印两个以上的字符)。 您有两种选择,首先使用hh
length修饰符将类型限制为1个字节,然后仅将值(unsigned char)
为(unsigned char)
,例如
printf("%02hhx ", (unsigned char)buff[i]);
您的逻辑也有点麻烦。 您应该使用if ... else if ... else
来处理二进制情况。 此外,当i >= read || buff[i] == 0
时,您将输出两个空格。 i >= read || buff[i] == 0
,所以您最好将测试结合起来。
简短的重写可能类似于以下内容(它将从作为第一个参数给出的文件中读取-如果没有给出参数,则将从stdin
读取)
#include <stdio.h>
#define OFFSET 16
int main (int argc, char const *argv[])
{
char buff[OFFSET] = "";
int read, address = 0, i;
FILE *fp = argc > 1 ? fopen (argv[1], "rb") : stdin;
if (!fp) {
perror ("fopen");
return 1;
}
while ((read = fread(buff, 1, sizeof buff, fp)) > 0) {
printf("%08x ", address);
address += OFFSET;
for (i = 0; i < OFFSET; i++) /* print hex values */
if (i >= read || buff[i] == 0)
printf(" ");
else
printf("%02hhx ", (unsigned char)buff[i]);
fputs ("| ", stdout); /* optional separator before ASCII */
for (i = 0; i < OFFSET; i++) /* print ascii values */
printf("%c", (buff[i] >= ' ' && buff[i] <= '~' ? buff[i] : ' '));
putchar ('\n'); /* use putchar to output single character */
}
if (fp != stdin)
fclose (fp);
}
(注意:如果您的编译器不支持hh
前缀,则强制转换本身就足够了)
仔细检查一下,如果您还有其他问题,请告诉我。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.