如何在C ++中创建十六进制转储实用程序?

时间:2013-05-29 01:47:33

标签: c++ hex binaryfiles dump utility

基本上,我需要使用C ++编写十六进制转储实用程序。它看起来像这样

Part of a Word document's hex dump using Visual Studio

(使用Visual Studio的Word文档的十六进制转储的一部分)

我想提示用户输入文件名,然后显示十六进制值以及翻译的ASCII字符。我仍然是处理二进制文件的新手,所以如果你能保持简单,那将非常感激。

2 个答案:

答案 0 :(得分:16)

我通常不会因为你的问题而这样做......但是这样做并没有太大的帮助,也许你可以从中学习。这是一个简单的程序,它只是从标准输入和输出中读取,其格式与您显示的大致相同。试一试here

<强>代码

#include <iostream>
#include <iomanip>

using namespace std;

int main()
{
    unsigned long address = 0;
    char c;

    cout << hex << setfill('0');
    while( cin.good() )
    {
        int nread;
        char buf[16];

        for( nread = 0; nread < 16 && cin.get(buf[nread]); nread++ );
        if( nread == 0 ) break;

        // Show the address
        cout << setw(8) << address;

        // Show the hex codes
        for( int i = 0; i < 16; i++ )
        {
            if( i % 8 == 0 ) cout << ' ';
            if( i < nread )
                cout << ' ' << setw(2) << (unsigned int)(unsigned char)buf[i];
            else 
                cout << "   ";
        }

        // Show printable characters
        cout << "  ";
        for( int i = 0; i < nread; i++)
        {
            if( buf[i] < 32 ) cout << '.';
            else cout << buf[i];
        }

        cout << "\n";
        address += 16;
    }
    return 0;
}

<强>输入

Hello there, this is a test binary file.
What do you think?

.

<强>输出

00000000  48 65 6c 6c 6f 20 74 68  65 72 65 2c 20 74 68 69  Hello there, thi
00000010  73 20 69 73 20 61 20 74  65 73 74 20 62 69 6e 61  s is a test bina
00000020  72 79 20 66 69 6c 65 2e  0a 57 68 61 74 20 64 6f  ry file..What do
00000030  20 79 6f 75 20 74 68 69  6e 6b 3f 0a 0a 2e         you think?...

答案 1 :(得分:0)

template<typename byte_type = std::uint8_t>
std::string hexdump(const byte_type* buffer, std::size_t size, const std::string& title = "HEXDUMP") {
  using namespace std;
  ostringstream ost;
  ost << title << '\n';
  const auto bytes = vector<byte_type>(buffer, buffer + size);
  for(auto p = cbegin(bytes) ; p < cend(bytes) ; ) {
    constexpr auto ptrSize = sizeof(void*);
    constexpr auto byteSize = sizeof(byte_type);
    constexpr auto wordsPerRow = 4;
    const auto bytesToGo = static_cast<unsigned>(std::distance(p, cend(bytes)));
    const auto nBytes = std::min(ptrSize, bytesToGo);
    const auto bytesPrinted = static_cast<unsigned>(std::distance(cbegin(bytes), p));
    const auto isFirstRow = bytesPrinted == 0;
    const auto isNewRow = (bytesPrinted % (ptrSize * wordsPerRow)) == 0;
    const auto isLastRow = (p + nBytes) == cend(bytes);

    if(isNewRow && !isLastRow) {
      if(!isFirstRow) {
        ost << '\n';
      }
      ost << hex << setw(ptrSize*2) << setfill('0') <<  bytesPrinted << "   ";
    }

    {
      for_each(p, p + nBytes, [&ost](byte_type byte) {
          ost << ' ' << hex << setw(byteSize*2) << setfill('0') << static_cast<unsigned>(byte);
        });
      ost << "   ";
    }

    if(isLastRow) {
      ost << '\n';
    }

    p += nBytes;
  }
  return ost.str();
}