什么是cout<< std :: ios :: hex吗?

时间:2015-12-01 21:35:48

标签: c++ std

这个问题来自我最近遇到的一个错误。我试图将一些整数值保存为文件为十六进制。举个例子,这就是我应该做的:

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 个答案:

答案 0 :(得分:17)

这实际上是 java.io.File file = new java.io.File("vowels.txt"); Scanner input = null; try { input = new Scanner(file); } catch (FileNotFoundException e) { e.printStackTrace(); } String fileContent = ""; while (input.hasNext()) { fileContent += input.next().toLowerCase(); } input.close(); int counter = 0; for (int i = 0; i<fileContent.length()-4;i++) { if(fileContent.charAt(i) == 'a'){ if(fileContent.charAt(i+1)=='e'){ if(fileContent.charAt(i+2)=='i') if(fileContent.charAt(i+3)=='o') if(fileContent.charAt(i+4)=='u'){ counter++; } } } } System.out.println("The file " + file + " has AEIOU in order " + counter + " times"); } 。它是一个实现定义的位掩码。在内部,流有一个名为fmtflags的整数,它存储格式的当前状态。

在您的实施中,std::ios_base::hex是标志hex。其他标志将指示它是否处于科学记数法模式,0x800是否打开等等。

boolalpha函数在std::hex中设置std::ios_base::hex标记。

所以你的输出是这个标志的整数值(自你之前发送fmtflags以来的十六进制)。

答案 1 :(得分:10)

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,表示带有前缀的整数值的基数:

  • 没有前缀=&gt;小数
  • 领先0x =&gt;十六进制
  • 领先的0(但没有x)=&gt;八进制

答案 2 :(得分:6)

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

  

将流str的基本域设置为十六进制,就像调用str.setf(std::ios_base::hex, std::ios_base::base field)

一样

std::ios::hex(又名std::ios_base::hex)是传递给setf方法的实际位掩码值。它的值是实现定义的,在你的情况下似乎是0x800