Получение флагов в потоках c ++ - PullRequest
2 голосов
/ 09 июня 2011

Как я могу использовать флаги в потоках c ++? Я знаю о ios_base::flags(), но когда я их cout или сравниваю, они не меняют значения даже с новым флагом. простая программа:

#include <iostream>
using namespace std;

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

не изменяет выведенное значение по умолчанию (по крайней мере для меня) 4098.

моя конечная цель - сравнить поток с флагами, чтобы увидеть, какие из них установлены, НЕ УСТАНОВИТЬ НОВЫЕ . Может кто-нибудь показать мне пример, как это сделать?

1 Ответ

2 голосов
/ 09 июня 2011

С этим кодом:

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 :: hex:

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));
...