简体   繁体   English

C++:将字节数组序列化为十六进制字符串

[英]C++: Serialize byte array to hex string

I (C++ newbie) am currently trying to implement the following function:我(C++ 新手)目前正在尝试实现以下功能:

std::string bytes_to_hex(const std::string &bytes);

The function should basically return a base16 encoding of a given byte array:该函数应该基本上返回给定字节数组的 ba​​se16 编码:

std::string input{0xde, 0xad, 0xbe, 0xef} => "deadbeef"

My first version doesn't quite work how I imagined:我的第一个版本并不像我想象的那样工作:

std::string bytes_to_hex(const std::string &bytes) {
    std::ostringstream ss;
    ss << std::hex;

    for (auto &c : bytes) {
        ss << std::setfill('0') << std::setw(2) << +c;
    }

    return ss.str();
}

With this function the output is:使用此函数,输出为:

ffffffdeffffffadffffffbeffffffef

After some experiments, I've found out that this version looks better:经过一些实验,我发现这个版本看起来更好:

std::string bytes_to_hex(const std::string &bytes) {
    std::ostringstream ss;
    ss << std::hex;

    for (const char &c : bytes) {
        ss << std::setfill('0') << std::setw(2) << +(static_cast<uint8_t>(c));
    }

    return ss.str();
}

The output is as expected:输出如预期:

deadbeef

My question is:我的问题是:

  • Why does the second version work and the first doesn't?为什么第二个版本有效而​​第一个版本无效? What is the main difference here?这里的主要区别是什么?
  • Is the second version correct implementation of my original intention or can there be other problems?第二个版本是正确实现了我的初衷还是会出现其他问题?

As mentioned in my comment, the unary + forces integer promotion .正如我在评论中提到的,一元+强制整数提升 When that happens, signed types are sign extened which for two's complement encoded integers means that negative numbers (where the left-most bit is 1 ) are left-padded with binary ones (ie 0xde becomes 0xffffffde ).当这种情况发生时,有符号类型会被符号扩展,这对于二进制补码编码的整数意味着负数(最左边的位是1 )用二进制数字左填充(即0xde变成0xffffffde )。

Also mentioned is that char can be either signed or unsigned , a decision that is up to the compiler.还提到了char可以是signedunsigned ,这取决于编译器。 Because of the output you get we can say that in your case char is actually signed char .由于您得到的输出,我们可以说在您的情况下char实际上是已signed char

The simple solution you found out is to first cast the character to an unsigned char , and then (with the unary + ) promote it to int .您发现的简单解决方案是首先将字符转换为unsigned char ,然后(使用一元+ )将其提升为int

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

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