41、C++ Primer 4th筆記,IO庫,格式化IO操作

weixin_34219944發表於2011-05-26

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 操作類似於管理流的條件狀態的rdstatesetstate操作。這種情況下,標準庫定義了一對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成員來取消scientificfixed所做的改變。

示例程式碼

#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則強制要求不跳過空白。

相關文章