How would I create a hex dump utility in C++?

◇◆丶佛笑我妖孽 提交于 2019-12-08 23:37:36

问题


Basically, I need to write a hex dump utility using C++. It'll look something like this

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

I want to prompt the user for a file name, and then display the hexadecimal values as well as the translated ASCII characters. I'm still new at working with binary files, so if you could keep it simple, that would be much appreciated.


回答1:


I don't normally do this for your kind of question.... But it doesn't take much to knock something like this up, and maybe you can learn from it. Here's a no-frills program that just reads from standard input and outputs in roughly the same format as you showed. Try it out here.

Code

#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;
}

Input

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

.

Output

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?...



回答2:


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();
}


来源:https://stackoverflow.com/questions/16804251/how-would-i-create-a-hex-dump-utility-in-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!