使用插入運算子和控制格式

本主題說明如何控制格式,以及如何為您自己的類別的建立插入運算子。 插入 (<<) 運算子已針對所有標準 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> 。 在輸出中,字串會在寬度為 6 的欄位中列印,並在寬度為 10 的欄位中列印整數:

   Zoot      1.23
  Jimmy     35.36
     Al     653.7
   Stan   4358.24

setwwidth 不會截斷值。 如果格式化輸出超過寬度,則會根據資料流的精確度設定列印整個值。 setwwidth 只會影響下欄欄位。 在列印欄位之後,欄位寬度會回復原預設行為 (必要寬度)。 不過,其他資料流格式選項在變更之前仍然有效。

對齊方式

輸出資料流預設為靠右對齊文字。 若要在上一個範例中靠左對齊名稱,並將數位靠右對齊,請取代 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

使用操作工具搭配 left 列舉值來設定 setiosflags 靠左對齊旗標。 這個列舉值定義于 類別中 ios ,因此其參考必須包含 ios:: 前置詞。 操作 resetiosflags 工具會關閉靠左對齊旗標。 與 和 不同 width ,和 setwresetiosflags 的效果是永久的 setiosflags

精確度

浮點精確度的預設值為六。 例如,數值 3466.9768 會列印為 3466.98。 若要變更此值列印的方式,請使用 setprecision 操作工具。 操作工具有兩個旗標: fixedscientific 。 如果 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 操作工具會清除這些旗標。

基數

octhex 操作工具會 dec 設定輸入和輸出的預設基底。 例如,如果您將 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 在 <iomanip> 中加入了 std::quoted 資料流操作工具。 插入時, quoted() 會以分隔符號(預設為雙引號 ' 「 ' ' 括住字串,並在擷取時運算元據流以擷取所有字元,直到找到最後的分隔符號為止。 任何內嵌引號會以逸出字元逸出(預設為'\\' )。

分隔符號只存在於資料流程物件中;它們不存在於擷取的字串中,但存在於 所 basic_stringstream::str 傳回的字串中。

插入和擷取作業的空白行為與字串在程式碼中的呈現方式無關,因此無論輸入字串是原始字串常值還是一般字串,加上引號的運算子都有效用。 輸入字串,無論其格式為何,都可以有內嵌引號、分行符號、定位字元等等,這些全都會由 quoted() 操作工具保留。

如需詳細資訊和完整的程式碼範例,請參閱 quoted

另請參閱

輸出資料流