C ++读取二进制文件并转换为十六进制

Posted

技术标签:

【中文标题】C ++读取二进制文件并转换为十六进制【英文标题】:C++ read binary file and convert to hex 【发布时间】:2012-03-26 04:27:42 【问题描述】:

我在读取二进制文件并将其字节转换为十六进制表示时遇到了一些问题。

到目前为止我已经尝试过:

ifstream::pos_type size;
char * memblock;

ifstream file (toread, ios::in|ios::binary|ios::ate);
  if (file.is_open())
  
    size = file.tellg();
    memblock = new char [size];
    file.seekg (0, ios::beg);
    file.read (memblock, size);
    file.close();

    cout << "the complete file content is in memory" << endl;

std::string tohexed = ToHex(memblock, true);


    std::cout << tohexed << std::endl;

   

转换为十六进制:

string ToHex(const string& s, bool upper_case)

    ostringstream ret;

    for (string::size_type i = 0; i < s.length(); ++i)
        ret << std::hex << std::setfill('0') << std::setw(2) << (upper_case ? std::uppercase : std::nouppercase) << (int)s[i];

    return ret.str();

结果:53514C69746520666F726D61742033

当我使用十六进制编辑器打开原始文件时,它会显示以下内容:

53 51 4C 69 74 65 20 66 6F 72 6D 61 74 20 33 00
04 00 01 01 00 40 20 20 00 00 05 A3 00 00 00 47
00 00 00 2E 00 00 00 3B 00 00 00 04 00 00 00 01
00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 05 A3
00 2D E2 1E 0D 03 FC 00 06 01 80 00 03 6C 03 D3

有没有办法使用 C++ 获得相同的所需输出?

工作解决方案(作者 Rob):

...

std::string tohexed = ToHex(std::string(memblock, size), true);

...
string ToHex(const string& s, bool upper_case)

    ostringstream ret;

    for (string::size_type i = 0; i < s.length(); ++i)
    
        int z = s[i]&0xff;
        ret << std::hex << std::setfill('0') << std::setw(2) << (upper_case ? std::uppercase : std::nouppercase) << z;
    

    return ret.str();

【问题讨论】:

"memblock 只包含前 15 个字节,停在空字节(第 16 个)" 你为什么这么说?我看不到您在哪里打印出memblock 的内容。我怀疑memblock 包含整个文件,但是您没有向我们展示的代码误解了它的内容。请将您的程序缩减为显示错误的最小完整程序,并将该程序发布在问题中。 sscce.org @Rob 好的,我应该重新发布前 15 个字节以便您更清楚吗? 假设这是一个家庭作业或某种学习任务,这里有一些提示:(1)你错过了一个while循环,(2)在一个流上调用tellg()你刚刚打开的还为时过早。 @develroot - 不,请告诉我们您是如何断定它只包含前 15 个字节的。 这就是我运行程序时显示的内容。 【参考方案1】:
char *memblock;
… 
std::string tohexed = ToHex(memblock, true);
…

string ToHex(const string& s, bool upper_case)

你的问题就在那里。构造函数std::string::string(const char*) 将其输入解释为以空字符结尾的字符串。因此,只有'\0' 之前的字符才会传递给ToHex。请尝试其中一种:

std::string tohexed = ToHex(std::string(memblock, memblock+size), true);
std::string tohexed = ToHex(std::string(memblock, size), true);

【讨论】:

好吧...这适用于十六进制转换...但我仍然有一个问题:结果不完全相同。 47 现在是 00,或者 2D 现在是 05..所有非 ASCII 字符也是如此。 @develroot - 如果有帮助,您的 ToHex 例程中有符号扩展错误。试试(s[i]&amp;0xff) 而不是(int)s[i] 这太棒了! :)

以上是关于C ++读取二进制文件并转换为十六进制的主要内容,如果未能解决你的问题,请参考以下文章

读取二进制文件碎片并转换为具有内存效率的整数

如何转换从文本文件中读取的整数并存储为具有16位整数的二进制文件?

将文件转换为 C/C++ 源代码数组的脚本/工具

怎样用C语言读取txt文件中的二进制数据并转为一维数组

java里怎样把文件转换成二进制

java里怎样把文件转换成二进制?