C++格式化輸出(詳解版)

2020-07-16 10:04:42
前面已經介紹過可用於流物件的 I/O 操作符,特別是 setw(n)、fixed、showpoint、setprecision(n)、left 和 right 操作符。這些操作符都可以在 fstream、ofstream 和 ostringstream 物件上使用。

為了這些操作符的用法,可以假設需要一個函數,該函數釆用一個 double 型別的實參,表示一個專案的價格(以美元為單位),並返回一個以美元符號 $ 開頭的字串,將價格的數值精確到小數點後兩位。例如,如果將 12.5 作為金額引數傳遞給函數,則函數將返回字串 $12.50。使用 ostringstream 即可輕鬆編寫該函數:
string dollarFormat(double amount)
{
    //建立 ostringstream 物件
    ostringstream outStr;
    //設定資訊格式並寫入outStr
    outStr << showpoint << fixed << setprecision(2);
    outStr << '$' << amount;
    //提取並返回outStr中的字串
    return outStr.str ();
}
下面的程式使用 dollarFormat 函數來編寫一個整齊格式化的價格表。價格是以二維陣列給出的。該程式設定了每個價格的格式並列印了一個包含所有價格的表格,每個價格均右對齊,列寬為 10:
//This program demonstrates the use of an ostringstream object to do sophisticated formatting.
#include <iostream>
#include <iomanip>
#include <sstream>
using namespace std;

string dollarFormat(double); // Function Prototype

int main()
{
    const int ROWS = 3, COLS = 2;
    double amount[ROWS][COLS] = {184.45, 7, 59.13, 64.32, 7.29, 1289 };
    // Format table of dollar amounts right justfied in columns of width 10
    cout << right;
    for (int row = 0; row< ROWS; row++)
    {
        for (int column = 0; column < COLS; column++)
        {
            cout << setw(10) << dollarFormat(amount[row][column]);
        }
        cout << endl;
    }
    return 0;
}
string dollarFormat(double amount)
{
    // Create ostringstream object
    ostringstream outStr;
    // Set up format information and write to outStr.
    outStr << showpoint << fixed << setprecision(2);
    outStr << '$' << amount;
    // Extract and return the string inside outStr.
    return outStr.str();
}
程式輸出結果:
   $184.45     $7.00
    $59.13    $64.32
     $7.29  $1289.00
表 1 列出了可以與 C++ 流物件一起使用的 I/O 操作符列表,並給出了簡要含義描述。

表 1 C++流物件
操作符 描 述
Dec 以十進位制格式顯示後續數位
endl 寫入新行並沖刷輸出流
fixed 使用固定點表示法表示浮點數
flush 沖刷輸出流
hex 以十六進位制輸入或輸出
left 左對齊輸出
oct 以八進位制輸入或輸出
right 右對齊輸出
scientific 使用科學表示法表示浮點數
setfill(ch) 使用 ch 填充字元
setprecision(n) 將浮點精度設定為n
setw(n) 將輸出欄位的寬度設定為n
showbase 列印數位時顯示基數(進位制)
noshowbase 列印數位時不要顯示基數(進位制)
showpoint 強制顯示小數點和尾隨零
noshowpoint 如果可能的話,不列印結尾零和小數點
showpos 在非負數前面列印一個加號
noshowpos 在非負數前面不列印加號

前面我們已經介紹過表 1 中的部分操作符。oct、dec 和 hex 操作符可以用於輸入和輸出流。它們允許使用八進位制、十進位制或十六進位制數位系統讀取或寫入數位。

下面的程式演示了如何使用 cin 和 cout 讀取和寫入十進位制、十六進位制和八進位制值。
//This program demonstrates input and output of numbers
//using the octal, decimal, and hexadecimal number systems.
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
    int a, b;
    //Read two decimals and print hex and octal equivalents
    cout << "Enter two decimal numbers: ";
    cin >> a >> b;
    cout << "The numbers in decimal: " << a << 't1' << b << endl;
    cout << "The numbers in hexadecimal: " << hex << showbase << a << 't' << b << endl;
    cout << "The numbers in octal: " << oct << a << 't' << b << endl;
    // Read some hexadecimals and print their decimal equivalents
    cout << "Enter two hexadecimal numbers:";
    cin >> hex >> a >> b;
    cout << "You entered decimal " << dec << a << 't' << b << endl;
    // Read some octals and print their decimal equivalents
    cout << "Enter two octal numbers:";
    cin >> oct >> a >> b;
    cout << "You entered decimal " << dec << a << 't' << b << endl;
    return 0;
}
程式輸出結果為:

Enter two decimal numbers: 23 45
The numbers in decimal: 23      45
The numbers in hexadecimal: 0x17        0x2d
The numbers in octal: 027       055
Enter two hexadecimal numbers:17 2d
You entered decimal 23  45
Enter two octal numbers:27 55
You entered decimal 23 45

前面已經介紹過,當一個程式將資料寫入一個開啟的檔案時,資料不會直接進入檔案。相反,資料儲存在與檔案相關的輸出緩衝區中,稍後在一個沖刷緩衝區的過程中才會傳送到檔案。通常情況下,如果緩衝區已滿或檔案關閉時,緩衝區才會被沖刷。endl 和 flush 操作符允許程式設計師隨時沖刷緩衝區,從而強制將緩衝的資料傳輸到檔案。

例如,以下語句將沖刷輸出流的緩衝區:

outFile << flush;

scientific 操作符使得浮點數以科學計數法表示,即形式為 d.dddEdd。填充字元是當列印的數位未填滿要列印的整個欄位時寫入的字元。預設情況下,填充字元為空。程式設計師可以使用 setfill 操作符來指定不同的填充字元。範例如下:

outFile << setfill ('%');

該語句將使用百分比字元(%)作為填充字元。