C++基礎——格式化輸出
阿新 • • 發佈:2019-02-13
似乎很少有人強調C++的格式化輸出的問題,那是因為因為c++的編譯器默默地做著許多格式化的動作,以保證C++ Style格式化輸出與C-style的格式化的一個根本不同,C++style的格式化輸出是型別安全的(type-safe),而C-style不是。當然,我們也可以定製這些格式化的動作,就像C那樣,而不全都拜託編譯器。
準備
標頭檔案
包含
iomanip
標頭檔案,iomanip
顧名思義,io manipulator(操縱器)。本文所用庫函式或者變數,只有std::boolalpha
在iostream
標頭檔案中以外,其他都在iomanip
。每使用
iomanip
標頭檔案的std
零、 輸出布林型別
bool b = bool(); // 顯式地呼叫其建構函式實現對基本型別的初始化
std::cout << std::boolalpha << b << std::endl; // 輸出為'false',而不是將bool型別轉化為‘0’
一、 域寬的設定
setw(n)
#include <iostream>
#include <iomanip>
int main(int , char**)
{
const int max = 10;
const int width = 6;
for (int row = 1; row < max; ++row)
{
for (int col = 1; col < max; ++col)
{
std::cout << std::setw(width) << row * col;
}
std::cout << std::endl;
}
return 0;
}
如上圖的輸出顯示,setw()預設是右對齊。
二、 對齊方式的設定
共有兩種對齊方式的設定:
std::ios::left
,std::ios::right
,所用到的api是std::setiosflags
,以及std::resetiosflags
。
for (int row = 1; row < max; ++row)
{
if (row%2) // 奇數行
std::cout << std::setiosflags(std::ios::left); // 設定對齊方式為左對齊
else
std::cout << std::resetiosflags(std::ios::left);
for(int col = 1; col < max; ++col)
{
std::cout << row * col;
}
std::cout << std::endl;
}
三、 精度的控制
std::setprecision(n)
double x = 800000./81;
std::cout << std::setprecision(2) << x << endl; // 9.9e+003
std::cout << std::setiosflags(std::ios::fixed)
<< std::setprecision(2)
<< x << std::endl; // 9876.54
// std::setiosflags(std::ios::fixed)
// 避免使用科學計數法?
使用setprecision()
設定的精度位數,最後的輸出結果是一種四捨五入的版本;
std::cout << std::setiosflags(std::ios::fixed)
<< std::setprecision(4) << 2./3 << std::endl; // 0.6667
不使用 <iomanip>標頭檔案中的相關 api,使用 std::cout 輸出流的成員函式也可實現精度的設定:
std::cout.precision(20);
四、 設定填充字元
std::setfill('')
void showDate(int m, int d, int y) // 月 日 年
{
std::cout << std::setfill('0');
std::cout << std::setw(2) << m << '/'
<< std::setw(2) << d << '/'
<< std::setw(4) << y << std::endl;
}
五、 10進位制、8進位制、16進位制
std::hex
,std::oct
unsigned long x = 64206;
std::cout << x
<< " in base 8 is \"" << std::oct << x << "\""
<< " in base 16 is \"" << std::hex << x << "\"" << std::endl;
C++庫函式並沒有提供一個任意進位制的轉換,如下是一個轉換版本:
std::string convBase(unsigned long val, long base)
{
std::string digits = "0123456789ABCDEF";
std::string ret;
if (base < 2 || base > 16)
ret = "base out of range";
else
{
do
{
ret = digits[val%base] + ret;
// != (ret != digits[val%base]), 否則順序將會是逆序
ret /= base;
}while(val);
}
return ret;
}
六、補充
禁止科學計數法
std::cout << std::fixed << someNumber<< std::endl;