從第一堂c語言課上的那個printf開始,格式化字串就成了我的夢魘。此後我還在很多地方遇到過它們:fprintf,sscanf以及cstring的format成員函式……。除了能記住%s(string的縮寫)代表字串,%d(decimal的縮寫)代表整數之外,每次用到格式化字串的地方我都要求助於msdn。
直到我看到c++的字串格式化方式後,我決定從此拋棄c的那套格式化字串的方法。
在c++裡格式化字串,用到的最多的類是:ostringstream以及它的寬字元版本wostringstream。
話不多說,如果要將乙個整數n格式化成字串以便輸出之用
cstring的方式是這樣的:
cstringstr;
str.format(_t("%d"), n);
ostringstream的方式:
ostringstreamost;
ost拋開效率不談,起碼不用再去記%d代表整數,%f代表浮點數,當然還有更複雜的格式控制輸出的那些%(此處省略200字……)。
稍微複雜一點,如果要將整數以16進製制的格式輸出(這個恐怕是整數輸出中最常用的功能了)
ostringstreamost;
ost如果以16進製制大寫的格式輸出:
ostringstreamost;
ost《可有時候希望以32位整數的方式來輸出的時候,在前面通常要補上多個0,這時可以這樣做:
ostringstreamost;
// 也許有更好的寫法
ost<<"0x"《比起格式化字串來輸入的字母更多,但我覺得這種以人話寫出來的方式比較好記:)
對於浮點數,最長用的格式化功能莫過於在小數點後保留x位的做法。
比如在小數點後保留6位:
ostringstreamost;
// 將輸出1234.567800
ost《保留3位
// 將輸出1234.568,已經替我們做好了四捨五入
ost《實現機制
c++使用一種稱為操控符的技術來控制格式化的輸出。
經典的hello world的c++版本大概是這樣的:
std::cout<<"helloworld"《對endl的輸出將引發下面這個過載了的《運算子的呼叫(摘自vs2008的ostream檔案):
_myt& __clr_or_this_calloperator<<(_myt& (__cdecl *_pfn)(_myt&))
... 而endl正好滿足了這個過載的運算子的引數的格式:
_crtimp2_pure inline basic_ostream>&
__clrcall_or_cdecl endl(basic_ostream>& _ostr)
... 這樣:cout《再來看個稍微複雜點的,看看語句ost《在iomanip.cpp裡找到setprecision的函式定義:
_mrtimp2 _smanip__cdeclsetprecision(streamsizeprec)
... 發現這個函式返回了乙個_smanip型別的物件。streamsize的型別是int,這裡的prec肯定是傳過來的3,那構造_smanip物件時的另乙個引數spfun是什麼東西?
同樣是在iomanip.cpp裡,spfun函式定義如下:
static void__cdeclspfun(ios_base&iostr, streamsizeprec)
... 發現在這個函式的內部,對流iostr呼叫了precesion函式。
運算子《有這樣乙個過載的版本:
templateclass _traits,
class _arg> inline
basic_ostream<_elem, _traits>&__clrcall_or_cdecl operator<<(
basic_ostream<_elem, _traits>&_ostr, const _smanip<_arg>& _manip)
... 這樣,第乙個引數就是cout,而第二個引數就是setprecision函式返回的乙個臨時的_smanip型別的物件。在《運算子內部,如果(*_manip._pfun)(_ostr,_manip._manarg);就是呼叫spfun函式並將cout和3傳過去就好了!
go on!看看_manip._pfun到底是什麼東西:
// template struct _smanip
template
struct _smanip
...; 既然當初在setprecision函式裡,傳遞的是spfun,那麼_pfun就是spfun函式的指標啦。ok,大功告成!c++的表現力很強大吧!
雖然繞了這麼大乙個彎子只不過為了呼叫一下cout.precision(3),那為什麼不這樣寫?
cout.precision(3);
cout<<1234.5678;
顯然寫成一條語句ost當用ostringstream格式化完畢後,通過呼叫它的str成員函式可以得到格式化後的字串:
ostringstreamost;
// 格式化的工作
string str = ost.str();
如果接下來要繼續在這個流物件上進行其它的格式化工作,那麼要先清空ostringstream的快取,傳遞乙個空字串就好。
ost.str("");
這是個gui盛行的年代,從標準輸入顯得已經不那麼重要了,但是從檔案讀入依然是個很重要的操作,可我一直都是用winapi進行檔案的讀寫的,以後也許會再寫一片與格式化輸入有關的文章。
C 字串格式化
c 字串格式化 1 格式化識別符號 標準的數學格式字串用於返回通常使用的字串。它們通常象x0這樣的格式。x是格式化識別符號,0是精度識別符號。格式識別符號號共有9種,它們代表了大多數常用的數字格式。就像下表所示 字母含義 c或ccurrency 貨幣格式 d或ddecimal 十進位制格式 十進位制...
C 格式化字串
在c 程式開發中,我們會經常需要獲得某種格式化的字串,比如 顏色值 ff00ff,貨幣 2.00,日期2012 03 14等等。在c 中格式化字串,一般會用到string.format 和.tostring 兩個函式。1.已知顏色的rgb值,獲取顏色的字串格式 ff00ff。ff0ff string...
C 格式化字串
格式字串的形式為 輸出最小寬度 精度 長度 型別 例如,d格式符表示 用十進位制整形格式輸出。f表示用實型格式輸出,5.2f 格式表示輸出寬度為5 包括小數點 幷包含2位小數。函式概要 printf 函式用於列印格式化字串到標準輸出流。函式原型 include.int printf const ch...