1、除了條件狀態之外,每個iostream物件還維持一個控制IO格式化細節的狀態。如整形值的基數,浮點值的精度,輸出元素的寬度等。標準庫還定義了一組操縱符來修改物件的格式狀態。操縱符(manipulator)是可用作輸入或輸出運算子的運算元,它是一個函式或物件(a manipulator is a function or object that can be used as an operand([計]運算元;運算物件) to an input or output operator(運算子).)。操縱符返回其應用於的流物件,所以可以在一個語句中輸出多個操縱符和資料。
2、操縱符羅列
表1 iostream 中定義的操縱符 |
||
|
boolalpha |
將真和假顯示為字串 |
x |
noboolalpha |
將真和假顯示為1,0 |
|
showbase |
產生指出數的基數的字首 |
x |
noshowbase |
不產生記數基數字首 |
|
showpoint |
總是顯示小數點 |
x |
noshowpoint |
有小數部分才顯示小數點 |
|
showpos |
顯示非負數中的+ |
x |
noshowpos |
不顯示非負數中的+ |
|
uppercase |
在十六進位制中列印0X,科學記數法中列印E |
x |
nouppercase |
在十六進位制中列印0x,科學記數法中列印e |
x |
dec |
用十進位制顯示(整形值,符點數不受影響) |
|
hex |
用十六進位制顯示(整形值,符點數不受影響) |
|
oct |
用八進位制顯示(同上) |
|
left |
在值的右邊增加填充字元 |
|
right |
在值的左邊增加填充字元 |
|
internal |
在符號和值之間增加填充字元 |
|
fixed |
用小數形式顯示浮點數 |
|
scientific |
用科學記數法顯示浮點數 |
|
boolalpha |
將真和假顯示為字串 |
|
flush |
重新整理ostream緩衝區 |
|
ends |
插入空字元,然後重新整理ostream緩衝區 |
|
endl |
插入換行符,然後重新整理ostream緩衝區 |
|
unitbuf |
在每個輸出操作之後重新整理緩衝區 |
x |
nounitbuf |
恢復常規緩衝區重新整理 |
x |
skipws |
為輸入操作符跳過空白 |
|
noskipws |
不為輸入操作符跳過空白 |
|
ws |
“吃掉”空白 |
注:帶 x 的是預設流狀態。 |
||
表2 iomanip 中定義的操縱符 |
||
setfill(ch) |
用 ch 填充空白 |
|
setprecision(n) |
將浮點精度置為 n |
|
setw(w) |
讀寫 w 個字元的值 |
|
setbase(b) |
按基數 b 輸出整數 |
3、讀寫操縱符的時候,不讀寫資料,相反,會採取某種行動。改變流格式狀態的操縱符通常為後續IO保留改變後的格式狀態。取消操縱符的任何狀態改變通常是最好的。一般而言,流應該在每個IO操作之後處於通常的預設狀態。大多數改變格式狀態的操縱符提供設定/復原對,一個操縱符將格式狀態置為新值而另一個進行復原,恢復常規預設格式。
4、用flags操作恢復格式狀態
flags 操作類似於管理流的條件狀態的rdstate和setstate操作。這種情況下,標準庫定義了一對flags函式:
• 不帶實參的 flags() 返回流的當前格式狀態。返回值是名為 fmtflags的標準庫定義型別。
• flags(arg) 接受一個實參並將流格式置為實參所指定的格式。
示例程式碼
void display(ostream& os)
{
//remember the current format state
ostream::fmtflags curr_fmt = os.flags();
//do output that uses manipulators that change the format state of os
os.flags(curr_fmt); //restore the original format state of os
}
5、控制輸出格式
有兩大類的輸出控制:控制數值的表示,以及控制填充符的資料和佈局。
示例程式碼
int main()
{
bool bool_val;
cout << boolalpha
<< bool_val
<< noboolalpha;
return 1;
}
6、控制浮點值的格式
1)對於浮點值的格式化,可以控制下面三個方面:
• 精度:顯示多少位數字(總位數)。
• 記數法:用小數還是科學記法法顯示。
• 對是整數的浮點值的小數點的處理。
示例程式碼
int main()
{
cout << "Precision: " << cout.precision()
<< ", value: " << sqrt(2.0) << endl;
int prev_precision = cout.precision(12);
cout << ", value: " << sqrt(2.0) << endl;
cout << setprecision(prev_precision);
cout << ", value: " << sqrt(2.0) << endl;
return 1;
}
2)恢復浮點值的預設記數法
與其他操縱符不同,我們必須呼叫unsetf成員來取消scientific或fixed所做的改變。
示例程式碼
#include <iostream>
#include "string"
#include "cmath"
using namespace std;
int main()
{
cout << sqrt(2.0) << '\n' << endl;
cout << scientific << sqrt(2.0) << endl;
cout << fixed << sqrt(2.0) << endl;
//reset to default handling for notation
cout.unsetf(ostream::floatfield);
cout << sqrt(2.0) << endl;
return 1;
}
7、填充輸出
• setw,指定下一個數值或字串的最小間隔。
• left,左對齊輸出。
• right,右對齊輸出。輸出預設為右對齊。
• internal,控制負值的符號位置。internal 左對齊符號且右對齊值,用空格填充介於其間的空間。
• setfill,使我們能夠指定填充輸出時使用的另一個字元。預設情況下,值是空格。
像 endl 一樣,setw 不改變輸出流的內部狀態,它只決定下一個輸出的長度。
示例程式碼
#include <iostream>
#include "string"
#include "cmath"
#include "iomanip"
using namespace std;
int main()
{
int i = -16;
double d = 3.14159;
cout << setfill('#')
<< "i: " << setw(12) << i << endl
<< "d: " << setw(12) << d << endl
<< setfill(' '); //restore normal pad character
return 1;
}
8、預設情況下,輸入操作符忽略空白(空格,製表符,換行符,進紙和回車)。noskipws則強制要求不跳過空白。