I/O 格式化旗標


I/O格式控制器可以對當時正在處理的串流改變格式,如果想要在程式進行過程中,讓所有的串流都維持您所指定的格式,則您可以使用格式化旗標,格式化旗標定義了一些值,您可以使用setf()與unsetf()來設定與取消格式化旗標。

以下先列出一些常用的格式化旗標:
ios::boolalpha 將真與假以true與false顯示
ios::dec 10進位顯示
ios::fixed 正常方式顯示(非科學記號)
ios::hex 16進位顯示
ios::left 靠左
ios::oct 8進位顯示
ios::scientific 科學記號
ios::showbase 顯示基底
ios::showpoint 顯示小數點
ios::showpos 正數顯示+
ios::skipws 忽略空白字元
ios::uppercase 字母大寫

您可以一次設定一個格式化旗標,如果要設定兩個格式化旗標,則可以使用 | 來連結,例如:
cout.setf(ios::showbase | ios::hex);

下面這個程式顯示一些基本的格式化旗標作用:
#include <iostream> 
using namespace std;

int main() {
cout.unsetf(ios::dec); // 取消10進位顯示
cout.setf(ios::hex | ios::scientific); // 16進位顯示或科學記號顯示
cout << 12345 << " " << 100 << endl;

cout.setf(ios::showpos | ios::showpoint); // 正數顯示 + 號且顯示小數點
cout << 10.0 << ": " << -10.0 << endl;

return 0;
}

執行結果:
3039  64
+1.000000e+001: -1.000000e+001

在程式中我們先解除了ios::dec格式旗標,這個動作並不是一定需要,但在某些編譯器中,這個旗標會覆蓋其它的旗標,所以我們仍先清除比較保險。

ios類別的成員函式flags()會傳回目前串流的格式化設定值,如果傳遞參數給它,則它會設定參數所指定的格式,並傳回上一個格式設定:
fmtflags flags();
fmtflags flags(fmtflags);

下面這個程式可以用來測試串流的格式設定:
#include <iostream> 
using namespace std;

int main() {
ios::fmtflags f;

cout.unsetf(ios::dec);
cout.setf(ios::oct | ios::showbase);

f = cout.flags();

if(f & ios::left) {
cout << "left flag on\n";
}
else {
cout << "left flag off\n";
}

if(f & ios::dec) {
cout << "dec flag on\n";
}
else {
cout << "dec flag off\n";
}

if(f & ios::showbase) {
cout << "showbase flag on\n";
}
else {
cout << "showbase flag off\n";
}

if(f & ios::oct) {
cout << "oct flag on\n";
}
else {
cout << "left flag off\n";
}

return 0;
}

執行結果:
left flag off
dec flag off
showbase flag on
oct flag on

下面這個程式片段告訴您,如何使用flags()一次設定所有指定的格式旗標:
ios::fmtflags f = ios::showpos | ios::showbase | ios::oct | ios::right;
cout.flags(f);