I(C ++ newbie)我正在尝试实现以下功能:
std::string bytes_to_hex(const std::string &bytes);
该函数基本上应该返回给定字节数组的base16编码:
std::string input{0xde, 0xad, 0xbe, 0xef} => "deadbeef"
我的第一个版本并不像我想象的那样完成:
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();
}
使用此功能输出为:
ffffffdeffffffadffffffbeffffffef
经过一些实验,我发现这个版本看起来更好:
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();
}
输出符合预期:
deadbeef
我的问题是:
答案 0 :(得分:1)
正如我的评论所述,一元+
部队integer promotion。当发生这种情况时,签名类型是符号扩展,对于two's complement编码的整数,这意味着负数(最左边的位是1
)用二进制数填充(即0xde
变为0xffffffde
)。
还提到char
可以是signed
或 unsigned
,这是由编译器决定的。由于您得到了输出,我们可以说char
实际上是signed char
。
您发现的简单解决方案是首先将角色投放到unsigned char
,然后(使用一元+
)将其提升为int
。