【问题标题】:Char array to hex string C++字符数组到十六进制字符串 C++
【发布时间】:2012-05-30 04:56:03
【问题描述】:

我之前搜索了char*hex 字符串,但我发现在hex 字符串的末尾添加了一些不存在的垃圾。我从套接字接收数据包,我需要将它们转换为 hex 用于日志的字符串(空终止缓冲区)。有人可以建议我为C++ 提供一个好的实现吗?

谢谢!

【问题讨论】:

  • 十六进制字符串到底是什么意思?
  • 您是否尝试修复实现?你能发布实现和一些输入/输出吗?
  • “在十六进制字符串的末尾添加一些不存在的垃圾” - 您可能正在将非空终止缓冲区传递给期望 LPSTR 的函数。并非所有的 char* 都是字符串。
  • 我猜是的,你能告诉我如何从空终止缓冲区中获取十六进制吗?

标签: c++ hex buffer byte


【解决方案1】:

假设数据是一个字符*。使用 std::hex 的工作示例:

for(int i=0; i<data_length; ++i)
    std::cout << std::hex << (int)data[i];

或者如果你想把它全部保存在一个字符串中:

std::stringstream ss;
for(int i=0; i<data_length; ++i)
    ss << std::hex << (int)data[i];
std::string mystr = ss.str();

【讨论】:

  • 您必须使用 std:setfill 和 std::setw 才能正确转换。见:stackoverflow.com/a/7639754/1731454
  • 这个答案不正确,会导致数据损坏。请参阅@oferei 上面评论中的链接以获取正确示例。
  • char* 数组元素直接转换为intunsigned int 将导致超过0x7F 的字节被不正确地“符号扩展”。您需要先将char 转换为uint8_t,然后再将其转换为unsigned int,以便正确表示字节。请参阅此示例:stackoverflow.com/questions/62934400
【解决方案2】:

这里有一些东西:

char const hex_chars[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };

for( int i = data; i < data_length; ++i )
{
    char const byte = data[i];

    string += hex_chars[ ( byte & 0xF0 ) >> 4 ];
    string += hex_chars[ ( byte & 0x0F ) >> 0 ];
}

【讨论】:

    【解决方案3】:

    最简单的:

    int main()
    {
        const char* str = "hello";
        for (const char* p = str; *p; ++p)
        {
            printf("%02x", *p);
        }
        printf("\n");
        return 0;
    }
    

    【讨论】:

    • 适用于 nul 终止字符串。所以很可能,它只会给他带来同样的问题,促使他提出问题。
    【解决方案4】:

    我在这里找到了很好的例子Display-char-as-Hexadecimal-String-in-C++:

      std::vector<char> randomBytes(n);
      file.read(&randomBytes[0], n);
    
      // Displaying bytes: method 1
      // --------------------------
      for (auto& el : randomBytes)
        std::cout << std::setfill('0') << std::setw(2) << std::hex << (0xff & (unsigned int)el);
      std::cout << '\n';
    
      // Displaying bytes: method 2
      // --------------------------
      for (auto& el : randomBytes)
        printf("%02hhx", el);
      std::cout << '\n';
      return 0;
    

    如上所示的方法1可能是更C++的方式:

    转换为无符号整数
    使用std::hex 将值表示为十六进制数字
    使用std::setwstd::setfill&lt;iomanip&gt; 格式化
    请注意,您需要针对 0xff 屏蔽强制转换 int 以显示 最低有效字节:
    (0xff &amp; (unsigned int)el)

    否则,如果设置了最高位,则强制转换将导致三个 最高有效字节设置为ff

    【讨论】:

    • nitpick - 方法 1 应该使用 static_cast(re: 更多 C++ 方式)
    • 奖励,如果您使用 std::vector&lt;unsigned char&gt;(这对于随机字节数组可能会更好一些),那么您不需要 0xff &amp; 部分。
    【解决方案5】:

    上面的代码 sn-p 在字符串中提供了不正确的字节顺序,所以我修复了一点。

    char const hex[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A',   'B','C','D','E','F'};
    
    std::string byte_2_str(char* bytes, int size) {
      std::string str;
      for (int i = 0; i < size; ++i) {
        const char ch = bytes[i];
        str.append(&hex[(ch  & 0xF0) >> 4], 1);
        str.append(&hex[ch & 0xF], 1);
      }
      return str;
    }
    

    【讨论】:

    • 这可能是对 K-ballo 答案的评论或应该是答案(您可以提及您已解决的问题)。请编辑。
    【解决方案6】:

    使用提升:

    #include <boost/algorithm/hex.hpp>
    
    std::string s("tralalalala");
    std::string result;
    boost::algorithm::hex(s.begin(), s.end(), std::back_inserter(result));
    

    【讨论】:

    【解决方案7】:

    您可以尝试使用此代码将字节从数据包转换为以空字符结尾的字符串并存储到“字符串”变量进行处理。

    const int buffer_size = 2048;
    // variable for storing buffer as printable HEX string
    char data[buffer_size*2];
    // receive message from socket
    int ret = recvfrom(sock, buffer, sizeofbuffer, 0, reinterpret_cast<SOCKADDR *>(&from), &size);
    // bytes converting cycle
    for (int i=0,j=0; i<ret; i++,j+=2){ 
        char res[2]; 
        itoa((buffer[i] & 0xFF), res, 16);
            if (res[1] == 0) {
                data[j] = 0x30; data[j+1] = res[0];
            }else {
                data[j] = res[0]; data[j + 1] = res[1];
            }
    }
    // Null-Terminating the string with converted buffer
    data[(ret * 2)] = 0;
    

    当我们发送带有十六进制字节 0x01020E0F 的消息时,变量“data”具有字符串“01020e0f”的 char 数组。

    【讨论】:

      【解决方案8】:

      你可以使用std::hex

      例如。

      std::cout << std::hex << packet;
      

      【讨论】:

      • 我不知道你认为std::hexchar* 输出的改变,但你应该构建一个工作演示。
      猜你喜欢
      • 2011-10-01
      • 1970-01-01
      • 2010-10-04
      • 1970-01-01
      • 2014-03-07
      • 2013-08-09
      • 2013-10-13
      相关资源
      最近更新 更多