cout << std::ios::hex是什么意思?(涉及IT技术)

18

这个问题源于我最近遇到的一个错误。我想把一些整数值以十六进制的形式保存在文件中。例如,我应该这样做:

cout << std::hex << value << endl;                 // (1)

但是出于疏忽,我把它使用成了以下形式:

cout << std::ios::hex << value << endl;            // (2) 

编译器没有报错,但显然结果不正确。我随机尝试了几个值,似乎(2)实际上给出了部分正确的结果,只是它会将800附加为前缀。我不明白800来自哪里,也找不到好的参考。有人能解释一下发生了什么吗?

cout << std::hex << 255 << endl;       // output: FF
cout << std::ios::hex << 255 << endl;  // output: 800ff

cout << std::hex << 135 << endl;       // output: 87
cout << std::ios::hex << 135 << endl;  // output: 80087

cout << std::hex << 11 << endl;        // output: b
cout << std::ios::hex << 11 << endl;   // output: 800b
3个回答

19

这实际上是std::ios_base::hex。它是一个实现定义的位掩码。在内部,流有一个称为fmtflags的整数,用于存储格式化的当前状态。

在您的实现中,hex是标志0x800。其他标志将指示它是否处于科学计数法模式,是否打开了boolalpha等等。

std::hex函数设置fmtflags中的std::ios_base::hex标志。

因此,您的输出是此标志的整数值(以十六进制表示,因为您之前发送了std::hex)。


11

std::hex是一个操作器,即一个具有特定签名的函数:

std::ios_base& hex(std::ios_base& stream) {
    stream.setf(std::ios_base::hex, std::ios_base::basefield);
    return stream;
}

对于流处理操作器,有一些特殊的输出运算符被定义。针对引用std::ios_base的版本有以下运算符(忽略了该运算符实际上是一个函数模板):

std::ostream& operator<< (std::ostream& out, std::ios_base&(*manip)(std::ios_base&));

当与流一起使用时,操纵器函数被调用并设置特定的格式标志,本例中为std::ios_base::hex(这就是std::ios::hex实际上的定义方式)。由于std::ios_base::hex是一组标志的成员(其他的是std::ios_base::decstd::ios_base::oct),因此设置它还需要清除该组中任何可能设置的其他标志。因此,setf()以掩码(std::ios_base::basefield)的形式调用,以清除任何其他潜在设置的标志。

格式标志std::ios_base::fmtflags是一种位掩码类型。值std::ios_base::hex是其中之一。在格式化时,您将得到某些数字,很可能是2的幂(但不一定是2的幂)。您看到的值只是使用十六进制表示法打印的0x800(即2048):设置任何格式化标志(除width()之外)都是"粘性的",也就是说,它们保持不变,直到取消设置该标志为止。如果要查看值2048(对于您正在使用的实现),则应使用

std::cout << std::dec << std::ios_base::hex << "\n";      // 2048
std::cout << std::hex << std::ios_base::hex << "\n";      // 800
std::cout << std::showbase << std::ios_base::hex << "\n"; // 0x800

最后一行设置了标志showbase,该标志指示整数值的基数带有前缀:

  • 无前缀 => 十进制
  • 前导0x => 十六进制
  • 前导0(但没有x)=> 八进制

6

std::hex是一个特殊的对象,当使用operator<<将其应用于流时,

就像调用str.setf(std::ios_base::hex, std::ios_base::base field)一样,将流str的基础字段设置为十六进制。

std::ios::hex(也称为std::ios_base::hex)是传递给setf方法的实际位掩码值。它的值由实现定义,并且在您的情况下似乎为0x800


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接