格式化字串 以C 的名義 zt

2021-06-10 04:52:15 字數 2702 閱讀 3706

從第一堂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...