2011-06-09 29 views
2

如何在C++流中使用标志?我知道ios_base::flags(),但当我cout他们或比较他们,即使有一个新的标志,他们不改变值。一个简单的程序:在C++流中检索标志

#include <iostream> 
using namespace std; 

int main(){ 
    cout << cout.flags() << endl;//4098 
    cout << std::hex << cout.flags() << endl;// 0x1002 
    return 0; 
} 

犯规的4098

我的最终目标改变输出默认值(至少对我来说)是比较流标志,看看哪些设置,不设置NEW ONES。任何人都可以告诉我一个如何做到这一点的例子吗?

+3

我相信这是我们的老朋友[未定义行为和顺序点(http://stackoverflow.com/questions/4638364/undefined-behavior-and-sequence-points-reloaded)一次。有人可以同意吗? – 2011-06-09 01:04:36

+0

我不问为什么会发生这种情况。我问的是如何比较cout中的标志,以便我可以在条件下使用比较 – cppnoob 2011-06-09 01:06:55

+0

@BenjaminLindley:这不是未定义的行为;看到我的答案。 – 2011-06-09 01:43:47

回答

2

有了这个代码:

cout << std::hex << cout.flags() << endl; 

编译器允许在此以评估它:

ios_base::fmtflags f = cout.flags(); // store value before applying std::hex 
cout << hex; 
cout << f; 
cout << endl; 

所以你不能保证能够“看到”标志改变这种方式。但是,它不是未定义的行为。

标志是一个“位掩码类型”,它被定义为具有某些属性 - 实际使用的类型是实现定义的,但整数,枚举和std :: bitsets是可能性。你可以用正常位处理运算符:^,&,|和〜:

bool is_hex(std::ios_base &s) { 
    return (s.flags() & s.basefield) == s.hex; 
} 
// is_oct is identical, except with s.oct 

// Nothing set in basefield means "determine base from input" for istreams, 
// and ostreams use base 10. This makes is_dec harder to write. 

bool is_anybase(std::istream &s) { 
    return (s.flags() & s.basefield) == 0; 
} 

bool is_dec(std::istream &s) { 
    std::ios_base::fmtflags base = s.flags() & s.basefield; 
    return base == dec; 
} 
bool is_dec(std::ostream &s) { 
    std::ios_base::fmtflags base = s.flags() & s.basefield; 
    return (base == dec) || (base == 0); 
} 
// Purposeful overload ambiguity on std::iostream. 
// In 0x, we could write: 
bool is_dec(std::iostream &s) = delete; 

举一个例子,这是十六进制怎样的std ::工作:

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

其中SETF的作用:

ios_base::fmtflags fmtflags = s.hex; // first parameter 
ios_base::fmtflags mask = s.basefield; // second parameter 
s.flags((s.flags() & ~mask) | (fmtflags & mask)); 
+0

我认为这个函数只在*只有* hexflag被设置时才起作用。 – Xeo 2011-06-09 01:33:35

+0

@Xeo:是的,如果只设置了十六进制,我的is_hex会给出true,这就是流的工作方式(使用num_get/put facets)。 – 2011-06-09 01:35:11

+0

我的不好,我不完全知道'basefield'是什么。 :)我认为这是如何设置所有的标志默认... – Xeo 2011-06-09 01:44:06