以十六进制形式打印的无符号字符太长

Printed unsigned chars as hex are too long

本文关键字:字符 无符号 十六进制 式打印      更新时间:2023-10-16

让我们假设我有一个非常简单的例子:

vector<unsigned char> bytes {0xFF, 0xFF, 0xFD};
for (const char & v: bytes) {
    cout << hex << setfill('0') << setw(2) << uppercase << static_cast<unsigned>(v) <<" ";
}
cout << endl;

这给出:

FFFFFFFF FFFFFFFF FFFFFFFD

然而,我希望它简短,比如:

FF FF FD

那么,为什么我要得到一些额外的"FFFFF"呢?

for (const char & v: bytes)

您正在隐式地将bytes中的每个元素转换为char,在您的平台上似乎是signed。然后,当您强制转换为unsigned时,char会进行符号扩展,最终会得到大的十六进制值。

将以上内容更改为以下之一

for (const unsigned char & v: bytes)
for (auto const& v: bytes)
for (auto v: bytes) // since it's only a char copying might be better

实时演示

如果在循环中保持char无符号,则会得到所需的结果:

for (const unsigned char & v: bytes) {
    //     ^^^^^^^^
    cout << hex << setfill('0') << setw(2) << uppercase << static_cast<unsigned>(v) <<" ";
}

autoauto&也可以工作,因为矢量元素是无符号的。

得到FF s的原因是系统上的char是有符号的,这意味着值在转换为整数时得到符号扩展。

演示。

正如其他人所说,之所以会发生这种情况,是因为您将元素强制转换为有符号的char。我更喜欢以这种方式使用for循环来防止此类错误:

vector<unsigned char> bytes{ 0xFF, 0xFF, 0xFD };
for (int i = 0; i < bytes.size(); i++) {
    cout << hex << setfill('0') << setw(2) << uppercase << static_cast<unsigned>(bytes[i]) << " ";
}

使用迭代器也是一个好主意。