【问题标题】:How to get a hex dump from a binary file into C如何从二进制文件中获取十六进制转储到 C
【发布时间】:2022-06-22 23:05:43
【问题描述】:

我正在涉足一些 Game Boy 保存状态黑客,我目前正忙于从 C 中的二进制文件中读取。我知道char 是一个字节,所以我正在读取字符使用以下代码

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

int main () {
   FILE *fp = NULL;
   char buffer[100];
   int filesize;

   fp = fopen("save file.srm", "r+"); //open
   if(fp == NULL) printf("File loading error number %i\n", errno); 
   fseek(fp, 0L, SEEK_END); //seek to end to get file size
   filesize = ftell(fp);
   printf("Filesize is %i bytes\n",filesize);
   
   fseek(fp, 0, SEEK_SET); //set read point at start of file
   fread(buffer, sizeof buffer, 1, fp);//read into buffer
   
   for(int i=70;i<80;i++) printf("%x\n", buffer[i]); //display
   
   fclose(fp);
   
   return(0);
}

我得到的输出是

Filesize is 32768 bytes
ffffff89
66
ffffff85
2
2
ffffff8b
44
ffffff83
c
0

我正在尝试以字节为单位加载,因此我希望输出的每一行都具有最大值 0xff。有人可以解释为什么我会得到 ffffff8b 吗?

【问题讨论】:

  • 这是什么strlen(buffer)+1?这些不是字符串:使用fread(buffer, sizeof buffer, 1, fp); 或更好的大小和计数反转为fread(buffer, 1, sizeof buffer, fp);,并使用返回的值来控制下一个循环。
  • 我也建议printf("%02x\n", buffer[i] &amp; 0xFF);
  • ... 或 printf("%02x\n", (unsigned char)buffer[i]);
  • 我猜文件大小是一样的。您正在打印非确定性内存。根据文件大小调整缓冲区大小。

标签: c binaryfiles


【解决方案1】:

if(fp == NULL) printf("File loading error number %i\n", errno);

当您检测到错误时,不要只打印一条消息。退出程序或采取措施纠正错误。

char buffer[10];

使用unsigned char 处理原始数据。 char 可能已签名,这可能会导致不良影响。

fread(buffer, strlen(buffer)+1, 1, fp);

buffer此时还没有被初始化,所以strlen(buffer)的行为没有被C标准定义。在任何情况下,您都不想使用buffer 中当前字符串的长度作为fread 的大小。你想要数组的大小。所以使用sizeof buffer(没有+1)。

for(int i=0;i&lt;10;i++)

不要迭代到十。迭代到fread 放入缓冲区的字节数。 fread 返回 size_t 值,即读取的项目数。如果将其用作size_t n = fread(buffer, 1, sizeof buffer, fp);,则项目数(在n 中)将是读取的字节数,因为将1 作为第二个参数表示要读取的每个项目都是一个字节。

printf("%x\n", buffer[i]);

要打印unsigned char,请使用%hhx。因为您的 buffer 已经签署了 char 元素,所以其中一些是负面的。在此printf 中使用时,它们被提升为负int 值。然后,由于%xprintf 试图将它们打印为unsigned int 值。二进制补码形式的负值中的所有额外位都显示出来了。

【讨论】:

  • 感谢您的出色回答,我根据@WeatherVane 的评论进行了编辑,然后才看到您的回答以消除strlen 的问题,我没有意识到我会得到如此快速的回复。跨度>
猜你喜欢
  • 2014-10-30
  • 2012-03-06
  • 1970-01-01
  • 1970-01-01
  • 2014-06-10
  • 1970-01-01
  • 2012-03-26
  • 2018-12-24
  • 1970-01-01
相关资源
最近更新 更多