C++標準庫筆記:13.7 格式化

格式標誌

格式標誌可以控制輸入輸出的格式,比如是否在正數前加+號,用八進制、十進制、十六進制來顯示數據等。

以下是訪問格式標誌的成員函數(定義在ios_base類中)

成員函數 意義
setf(flags) 增加標誌,返回修改前的所有標誌
setf(flags, mask) 增加標誌,mask參數存放的標誌則被清除,返回修改前的所有標誌
unsetf(flags) 清除標誌
flags() 返回當前所有標誌
flags(flags) 將flags設爲新的格式標誌,返回修改前的所有標誌
copyfmt(stream) 從stream中複製所有格式定義

說明:
setf(flags, mask)舉例: std::cout.sef( std::ios::hex, std::ios::basefield);
其中標誌位ios::basefield是hex|oct|dec三個標誌的組合,其它標誌位定義參考如下,

static const _Fmtflags skipws = (_Fmtflags)_IOSskipws;
static const _Fmtflags unitbuf = (_Fmtflags)_IOSunitbuf;
static const _Fmtflags uppercase = (_Fmtflags)_IOSuppercase;
static const _Fmtflags showbase = (_Fmtflags)_IOSshowbase;
static const _Fmtflags showpoint = (_Fmtflags)_IOSshowpoint;
static const _Fmtflags showpos = (_Fmtflags)_IOSshowpos;
static const _Fmtflags left = (_Fmtflags)_IOSleft;
static const _Fmtflags right = (_Fmtflags)_IOSright;
static const _Fmtflags internal = (_Fmtflags)_IOSinternal;
static const _Fmtflags dec = (_Fmtflags)_IOSdec;
static const _Fmtflags oct = (_Fmtflags)_IOSoct;
static const _Fmtflags hex = (_Fmtflags)_IOShex;
static const _Fmtflags scientific = (_Fmtflags)_IOSscientific;
static const _Fmtflags fixed = (_Fmtflags)_IOSfixed;
static const _Fmtflags boolalpha = (_Fmtflags)_IOSboolalpha;
static const _Fmtflags _Stdio = (_Fmtflags)_IOS_Stdio;
static const _Fmtflags adjustfield = (_Fmtflags)(_IOSleft
    | _IOSright | _IOSinternal);
static const _Fmtflags basefield = (_Fmtflags)(_IOSdec
    | _IOSoct | _IOShex);
static const _Fmtflags floatfield = (_Fmtflags)(_IOSscientific
    | _IOSfixed);

爲了與IO操作符<<、>>配合使用,實現了以下兩個操控器(帶參數)來設置格式標誌

操控器 意義
std::setiosflags(flags) 將flags設爲格式標誌(調用setf(flags) )
std::resetiosflags(mask) 清除mask所標識的一組標誌(調用setf(0, mask) )

例如:
cout << std::resetiosflags( ios::basefield ) << std::setiosflags( ios::hex ) << 15 << endl;
輸出:
f

布爾值 的IO格式

由標誌boolalpha來控制,若設置了此標誌,便以文字表示,否則又數據表示,缺省的未被設立。注:此標誌被設立,就一直生效,除非清除此標誌

爲了與操作符<<、>>配合使用,實現了以下操控器

操控器 意義
std::boolalpha 設立標誌ios::boolalpha
std::noboolalpha 清除標誌ios::boolalpha

例如以下

cout << std::boolalpha << true << endl;
cout << false << endl;

輸出的爲:
true
false

字段寬度、填充字符、位置對齊

字段寬度、填充字符由成員函數控制,位置對齊方式則由格式標誌來控制。

成員函數 意義
width() 返回當前字符寬度
width(val) 設置當前字符寬度,並返回先前的字符寬度
fill() 返回當前填充字符
fill(c) 設置當前填充字符,並返回先前填充字符

以上表格中,函數width調用後的作用爲一次性的,即執行了任意格式化IO操作後,就會恢復width的值爲缺省狀態。而fill設置的則一直生效,除非重新設置。例如:

//以^符號填充
cout.fill( '^' );

cout.width( 4 );
cout << 1 << endl;

//恢復默認width
cout << 1 << endl;

位置對齊格式標誌如下:

掩碼 標誌 意義
ios::adjustfield ios::left 左對齊
ios::right 右對齊
ios::internal 符號靠左對齊,數值靠右對齊
None 右對齊(默認)

同樣,也提供了對應的操控器

  • std::setw(val),相當於widht(val)
  • std::setfill(c),相當於fill(c)
  • std::left,相當於setf( ios::left, ios::adjustfield)
  • std::right,相當於setf(ios::left, ios::adjustfield)
  • std::internal,相當於setf(ios::internal, ios::adjustfield)
  • -

正號、大寫字符

由格式標誌: ios::showpos、ios::uppercase來控制。ios::showpos被設置了,則在正數前顯示+號,ios::uppercase標誌被設置了,則針對十六進制、科學記號等的字母就以大寫的格式輸出,對字符串是不會有影響的。

同樣,也提供了對應的操控器

  • std::showpos
  • std::noshowpos
  • std::uppercase
  • std::nouppercase

注:此兩個標誌被設立,就一直生效,除非清除此標誌

數值進制

由格式標誌控制

  • ios::oct,以八進制進行讀寫
  • ios::dec,以十進制進行讀寫
  • ios::hex,以十六進制進行讀寫
  • none,以十進制輸出;讀取時則視起始字符而定
  • ios::showbase, 若被設置,則顯示數字的進制,八進制以0開頭,十六進制則以0x開頭

同樣的,也有相應的操作器

  • std::oct
  • std::dec
  • std::hex
  • std::showbase
  • std::noshowbase

注:此四個標誌被設立,就一直生效,除非清除此標誌

浮點數表示法

浮點數表示由格式標誌控制

  • ios::fixed,使用小數表示法
  • ios::scientific,使用科學計數表示法
  • None,使用上述兩者中最適合者(默認)
  • ios::showpoint,總是書寫小數點

精度控制成員函數

  • precision(),返回當前浮點數精度
  • precision(val),設置浮點數精度

對應操控器

  • std::showpoint
  • std::noshowpoint
  • std::setprecision(val)
  • std::fixed
  • std::scientific

注:以上標誌被設立,就一直生效,除非清除此標誌,精度被設置,也一樣

一般性格式定義

格式標誌

  • ios::skipws,調用>>讀取數值時,跳過起始空格,默認設置此標誌
  • ios::unitbuf,每次輸出後,清空output緩衝區

操控器

  • std::skipws
  • std::noskipws
  • unitbuf
  • nounitbuf

注:以上標誌被設立,就一直生效,除非清除此標誌

國際化

ios_base類定義了數個成員函數來支持國際化

  • imbue(loc),設置locale對象
  • getloc(),返回當前locale對象
  • widen(c),將char型別c轉換成stream字符集中的
  • narrow(c, def),widen的逆操作

總結

  • 格式標誌ios::width是一次性的 ,即執行了任意格式化IO操作後,就會恢復width的值爲缺省狀態
  • std::ws,這個操控器也是一次性的,文章http://blog.csdn.net/s634772208/article/details/72852975介紹了此操控器
  • 注意std::skipwsstd::ws的區別,前者是表示調用>>時,跳過起始空格,後者讀取時忽略空格,並且是一次性的。

以下演示std::noskipws的用法:

//此處若輸入(_表空格):_1space
//則啥也不輸出,因爲>>讀取字符串時是以空格來判斷是否結束的
//第一個空格沒被跳過,表示結束讀取,因爲啥也沒讀到,流被設置讀取失敗
std::string strTemp;
std::cin >> std::noskipws;
while( cin >> strTemp )
{
    cout << strTemp << endl;
}
//此處會一個字符一個字符的讀取,空格也會被讀取
//若輸入: _a_b
//則輸出:
//_
//a
//_
//b
char c;
cin >> std::noskipws;
while( cin >> c )
{
    if ( c == '\n')
    {
        continue;
    }
    cout << c << endl;
}
發佈了164 篇原創文章 · 獲贊 106 · 訪問量 33萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章