简体   繁体   English

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

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

Basically, I need to write a hex dump utility using C++.基本上,我需要使用 C++ 编写一个十六进制转储实用程序。 It'll look something like this它看起来像这样

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

(Part of a Word document's hex dump using Visual Studio) (使用 Visual Studio 的 Word 文档的十六进制转储的一部分)

I want to prompt the user for a file name, and then display the hexadecimal values as well as the translated ASCII characters.我想提示用户输入文件名,然后显示十六进制值以及转换后的 ASCII 字符。 I'm still new at working with binary files, so if you could keep it simple, that would be much appreciated.我在处理二进制文件方面还是新手,所以如果你能保持简单,那将不胜感激。

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;
    
    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?...
#include <iostream>
#include <vector>
#include <iomanip>
#include <numeric>

template<typename byte_type = std::uint8_t, typename container_type = std::vector<std::vector<byte_type>>>
container_type arrange_bytes(const byte_type* buffer, const std::size_t size, const std::size_t w = 16) {
  return std::accumulate(buffer, buffer + size, container_type{{}}, [w](auto& acc, const byte_type byte) {
    if(acc.back().size() >= w) {
      acc.push_back({});
    }
    acc.back().push_back(byte);
    return acc;
  });
}

std::string init_text_row(const int offset) {
  std::ostringstream ost{};
  ost << std::hex << std::setfill('0') << std::setw(8) << offset;
  return ost.str();
}

template<typename byte_type = std::uint8_t>
std::string format_row(const std::vector<byte_type>& bytes, const int offset) {
  auto init = init_text_row(offset);
  return std::accumulate(bytes.begin(), bytes.end(), init, [](auto& acc, const auto& byte) {
      std::ostringstream ost{};
      ost  << ' ' << std::hex << std::setfill('0') << static_cast<unsigned>(byte);
      return acc + ost.str();
  });
}

template<typename byte_type = std::uint8_t, typename container_type = std::vector<std::vector<byte_type>>>
std::string format_bytes(const container_type& bytes) {
  struct memory {
    std::string data = {};
    int offset = 0;
  };
  return std::accumulate(bytes.begin(), bytes.end(), memory{}, [](auto& acc, const auto& row) {
    acc.data += format_row(row, acc.offset) + '\n';
    acc.offset += row.size();
    return acc;
  }).data;
}

template<typename byte_type = std::uint8_t>
std::string hexdump(const byte_type* buffer, std::size_t size) {
  return format_bytes(arrange_bytes(buffer, size));
}

#include <cstring>

int main() {
  const auto* message = "Hello, world! I am Simon the Sourcerer and I am a mighty pirate!";
  const auto len = std::strlen(message);
  std::cout << hexdump(message, len) << std::endl;
  return 0;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM