使用插入運算子和控制格式
本主題說明如何控制格式,以及如何為您自己的類別的建立插入運算子。 插入 (<<
) 運算子已針對所有標準 C++ 資料類型預先排定,可將位元組傳送至輸出資料流物件。 插入運算子會使用預先定義的「操作工具」,這是會變更整數引數預設格式的元素。
您可以使用下列選項來控制格式:
輸出寬度
若要對齊輸出,您可以藉由將操作工具放在 setw
數據流中或呼叫 width
成員函式,來指定每個項目的輸出寬度。 此範例會以至少 10 個字元的寬度靠右對齊資料行中的值:
// output_width.cpp
// compile with: /EHsc
#include <iostream>
using namespace std;
int main( )
{
double values[] = { 1.23, 35.36, 653.7, 4358.24 };
for( int i = 0; i < 4; i++ )
{
cout.width(10);
cout << values[i] << '\n';
}
}
1.23
35.36
653.7
4358.24
任何寬度少於 10 個字元的值,都會加入前置空白。
若要填補欄位,請使用 fill
成員函式,以設定具有指定寬度之字段的填補字元值。 預設值為空白。 若要以星號填補數字數據行,請修改上 for
一個迴圈,如下所示:
for (int i = 0; i <4; i++)
{
cout.width(10);
cout.fill('*');
cout << values[i] << endl;
}
endl
操作工具會取代新行字元 ('\n'
)。 輸出如下所示:
******1.23
*****35.36
*****653.7
***4358.24
若要指定同一行中的資料元素寬度,請使用 setw
操作工具:
// setw.cpp
// compile with: /EHsc
#include <iostream>
#include <iomanip>
using namespace std;
int main( )
{
double values[] = { 1.23, 35.36, 653.7, 4358.24 };
const char *names[] = { "Zoot", "Jimmy", "Al", "Stan" };
for( int i = 0; i < 4; i++ )
cout << setw( 7 ) << names[i]
<< setw( 10 ) << values[i] << endl;
}
成員 width
函式會在中 <iostream>
宣告。 如果您使用 setw
或任何其他操作工具搭配自變數,則必須包含 <iomanip>
。 在輸出中,字串會在寬度為 7 的欄位中列印,並在寬度為 10 的欄位中列印整數:
Zoot 1.23
Jimmy 35.36
Al 653.7
Stan 4358.24
setw
和 width
不會截斷值。 如果格式化輸出超過寬度,則會根據資料流的精確度設定列印整個值。
setw
和 width
只會影響下列欄位。 在列印欄位之後,欄位寬度會回復原預設行為 (必要寬度)。 不過,其他資料流格式選項在變更之前仍然有效。
對齊方式
輸出資料流預設為靠右對齊文字。 若要在上一個範例中靠左對齊名稱,並將數位靠右對齊,請取代 for
迴圈,如下所示:
for (int i = 0; i <4; i++)
cout << setiosflags(ios::left)
<< setw(6) << names[i]
<< resetiosflags(ios::left)
<< setw(10) << values[i] << endl;
輸出如下所示:
Zoot 1.23
Jimmy 35.36
Al 653.7
Stan 4358.24
使用操作工具搭配setiosflags
列舉值來設定left
靠左對齊旗標。 這個列舉值定義於 類別中 ios
,因此其參考必須包含 ios::
前置詞。 操作 resetiosflags
工具會關閉靠左對齊旗標。 與 和 不同width
,和 setw
setiosflags
的效果是永久的resetiosflags
。
精確度
浮點精確度的預設值為六。 例如,數值 3466.9768 會列印為 3466.98。 若要變更此值列印的方式,請使用 setprecision
操作工具。 操作工具有兩個旗標: fixed
和 scientific
。 如果 fixed
已設定,數位會列印為 3466.976800。 如果 scientific
已設定,則會列印為 3.4669773+003。
若要以一個有效位數顯示對齊中顯示的浮點數,請取代 for
迴圈,如下所示:
for (int i = 0; i <4; i++)
cout << setiosflags(ios::left)
<< setw(6)
<< names[i]
<< resetiosflags(ios::left)
<< setw(10)
<< setprecision(1)
<< values[i]
<< endl;
程式會列印這份清單:
Zoot 1
Jimmy 4e+01
Al 7e+02
Stan 4e+03
若要消除科學表示法,請在迴圈之前 for
插入此語句:
cout << setiosflags(ios::fixed);
使用固定標記法時,程式會在小數點後面列印一位數。
Zoot 1.2
Jimmy 35.4
Al 653.7
Stan 4358.2
如果您將 ios::fixed
旗標變更為 ios::scientific
,則程式會列印下列專案:
Zoot 1.2e+00
Jimmy 3.5e+01
Al 6.5e+02
Stan 4.4e+03
同樣地,程式會在小數點後面列印一位數。
ios::fixed
如果設定 或 ios::scientific
,有效位數值會決定小數點後面的位數。 如果未設定任一旗標,精確度值將會決定有效位數的總數。
resetiosflags
操作工具會清除這些旗標。
基數
、 dec
和 oct
操作工具會hex
設定輸入和輸出的預設基底。 例如,如果您將 hex
操作工具插入輸出數據流中,物件會將整數的內部數據表示正確轉譯為十六進位輸出格式。 如果 uppercase
旗標是清楚的,則數位會以 f 為單位以數字顯示;否則,它們會顯示在大寫中。 默認的基數為 dec
(十進位)。
使用引號的字串 (C++14)
當您將字串插入數據流時,您可以藉由呼叫 stringstream::str()
成員函式,輕鬆地擷取相同的字串。 不過,如果您想要使用擷取運算符將數據流插入新字串的稍後點,您可能會收到非預期的結果,因為 >>
運算符在找到第一個空格符時預設會停止。
std::stringstream ss;
std::string inserted = "This is a sentence.";
std::string extracted;
ss << inserted;
ss >> extracted;
std::cout << inserted; // This is a sentence.
std::cout << extracted; // This
此行為可以手動修改,但為了讓字串的往返更簡便、C++14 在 std::quoted
中加入了 <iomanip>
資料流操作工具。 插入時, quoted()
會以分隔符(預設為雙引號 ' ' ' 括住字串,並在擷取時操作數據流以擷取所有字元,直到找到最後的分隔符為止。 任何內嵌引號會以逸出字元逸出(預設為'\\' )。
分隔符只存在於數據流物件中;它們不存在於擷取的字串中,但存在於 所 basic_stringstream::str
傳回的字串中。
插入和擷取作業的空白行為與字串在程式碼中的呈現方式無關,因此無論輸入字串是原始字串常值還是一般字串,加上引號的運算子都有效用。 輸入字串,無論其格式為何,都可以有內嵌引號、換行符、製表元等等,這些全都會由 quoted()
操作工具保留。
如需詳細資訊和完整的程式碼範例,請參閱 quoted
。