C 格式化字串問題,C 格式化字串問題

2021-05-05 19:30:12 字數 5307 閱讀 5244

1樓:閃亮登場

1 sprintf,snprintf,vsnprintf家族

這幾個函式大家都不陌生,平時用的也比較多。下面我就它的優點簡單的做一個總結:

· 易用性與清晰性:

使用snprintf的常用格式化標誌及其他們的各種組合,使用就變得簡潔明瞭,沒有任何拐彎抹角之處。

· 效率最佳:

能夠直接利用現有的緩衝區,當然你的程式可能根本就不會在乎這點效率的優化。永遠不要過早進行優化。

這個家族的函式最致命的缺陷在於長度安全性。

sprintf是引起緩衝區溢位錯誤的原因之一。snprintf和vsnprintf稍微好些,但也會引起其他的問題。sprintf已經無可救藥了,不提也罷,這個儘量少用。

snprintf和vsnprintf雖然是對長度是安全的,但對於過長的字串,他也暴露了很多他的無奈。

看個例子:

void cstring::format(lpctstr lpszformat,...)

allocated += result;

line = (char*)realloc(line,allocated);

}va_end(ap);

if (line)

else

if (pfree)

}這個函式封裝了vsnprintf,使其可以對任意長度的字串都可以格式化。但仔細分析這個函式,其實他不能對任意長度的字串進行格式化,只能最多格式化2048個字元,即while迴圈只能執行一次,原因在於:vsnprintf只能執行一次,根據man手冊中vsnprintf的解釋,在執行vsnprintf之後,ap的值是未定義的,因此,在while執行第二次的時候,誰知道會發生什麼事情那。

因此,對於不能確定其長度的字串,而這個字串的長度而有可能變的很大的時候,儘量不要用這個封裝的format函式,要自己來控制字串的長度,自己來分配空間,自己呼叫snprintf函式。

這個家族函式的另一個確定是:不是型別安全的。

比如對於int i來說,snprintf(buf,sizeof(buf),"%4c",i)輸出的是字元而不是整數,其實把整數當做字元也沒有什麼錯,這個問題也不嚴重,但是如果一不小心寫成snprintf(buf,sizeof(buf),"%4s",i),這個問題就大發了,程式可能會立即崩潰或至少偶發性的崩潰。這個只是個簡單的例子,其他也有類似問題需要注意。

2 std::stringstream

c++中字串化最常見的設施就是stringstream了。

一個簡單的例子:

void format(int i,string& s)

看一下stringstream的特點:

易用性和簡單性:

這個顯然和snprintf比起來要差一點了,一行可以完成的,現在變成了3行完成。並且不易於學習,你要學習諸如setw類似的函式來控制格式。

效率:stringstream會自己分配一份單獨的緩衝區來存放結果,另外還需要一個輔助性的物件,通常所有這些都意味著需要進行額外的記憶體分配。

長度安全性:

stringstream內部的basic_stringbuf緩衝類會根據需要自動增長,以便容納需要存放的資料,因此是長度安全的。

型別安全性:

使用operator《和過載決議,即便是對於那些提供了自己的流插入操作的自定義流型別,也總能夠實現型別安全,不會因為型別不符而導致一些神祕的執行時錯誤。

3 std::strstream

strstream是要被遺棄的,在c++03標準將它表明為deprecate(不贊成的),因此很多c++書籍頂多也只是略微提及一下。

void format(int i,char* buf,int buflen)

易用性和清晰性:

lexical_cast的**最為直接地表達了實際的意圖。

效率:lexical_cast是stringstream類的一個包裝,因此它至少需要和stringstream一樣的記憶體分配次數。

在長度安全性,型別安全性方面,它和stringstream有一樣的表現。

2樓:匿名使用者

有的編譯器會對這個問題提出警告,經驗之談就是開啟並且需要消除所有警告f:\work tmp\test>gcc -wall -s -c c_q12.c

c_q12.c:2:6: warning: return type of 'main' is not 'int' [-wmain]

c_q12.c: in function 'main':

c_q12.c:8:2: warning: format '%s' expects a matching 'char *' argument [-wformat]

另外,為了健壯,應該儘量用snsprintf,避免緩衝區溢位

3樓:匿名使用者

不知道你程式的具體實現是什麼,所以也侷限了大家的思想,我覺得還是得自己本人判斷使用者的輸入,加上人性化的輸入前提示和輸入錯誤提示並返回重新輸入等解決方案。

c++的string有沒有字串格式化

4樓:你好啊月亮

有的,可以根據以下步驟。

1. 在將各種型別的資料構造成字串時,sprintf 的強大功能很少會讓你失望。由於sprintf 跟printf 在用法上幾乎一樣,只是列印的目的地不同而已,前者列印到字串中,後者則直接在命令列上輸出。

這也導致sprintf 比printf 有用得多。

2. sprintf 是個變參函式,定義如下:int sprintf( char *buffer, const char *format [, argument] ...

);除了前兩個引數型別固定外,後面可以接任意多個引數。而它的精華,顯然就在第二個引數:格式化字串上。

3. printf 和sprintf 都使用格式化字串來指定串的格式,在格式串內部使用一些以"%"開頭的格式說明符(format specifications)來佔據一個位置,在後邊的變參列表中提供相應的變數,最終函式就會用相應位置的變數來替代那個說明符,產生一個呼叫者想要 的字串。

4. sprintf 最常見的應用之一莫過於把整數列印到字串中,所以,spritnf 在大多數場合可以替代itoa。

c++格式化字串中%x的問題

5樓:匿名使用者

對於整數格式控制符而言(u,d,i,x,o),小數點後面的這個數字指定一個數字最少有幾位數,如果不足這個位數,則會在前面補0

6樓:

%.幾 是代表小數點後幾位,只是對%f而言。

而對於16進位制,不存在小數顯示的問題,況且,對於c語言中的格式化樣式,每一種都是不相同的,因此,對於%x的處理,也不能以%f的方式給以解釋。

%c 只處理整數,對於非整數之類的數值是無效的。

%2x %.2x %0.2x 其效果是一樣的。

c++中字串的格式化輸出問題!請高手指教!!!

7樓:匿名使用者

#include

setw(n)用法: 通俗地講就是預設寬度為了方便對齊只要將n值調整好即可,

參考如 cout<

8樓:劍起飛虹

用set(n)啊,不過前面要有#include的標頭檔案,此標頭檔案專門用於控制輸入輸出的。

set(n)設定欄位寬度為n位

不過還要設定成左對齊的方式。具體為:

cout<

#include

using namespace std;

int main()

}return 0;}

9樓:匿名使用者

3.控制浮點數值顯示

使用setprecision(n)可控制輸出流顯示浮點數的數字個數。c++預設的流輸出數值有效位是6。

如果setprecision(n)與setiosflags(ios::fixed)合用,可以控制小數點右邊的數字個數。setiosflags(ios::

fixed)是用定點方式表示實數。

如果與setiosnags(ios::scientific)合用, 可以控制指數表示法的小數位數。setiosflags(ios::scientific)是用指數方式表示實數。

例如,下面的**分別用浮點、定點和指數方式表示一個實數:

//*********************

//** ch2_1.cpp **

//*********************

#include

#include //要用到格式控制符

void main()

執行結果為:

3.14286

3 33.1

3.14

3.143

3.14285714

3.14285714e+00

該程式在32位機器上執行通過。

在用浮點表示的輸出中,setprecision(n)表示有效位數。

第1行輸出數值之前沒有設定有效位數,所以用流的有效位數預設設定值6:第2個輸出設定了有效位數0,c++最小的有效位數為1,所以作為有效位數設定為1來看待:第3~6行輸出按設定的有效位數輸出。

在用定點表示的輸出中,setprecision(n)表示小數位數。

第7行輸出是與setiosflags(ios::fixed)合用。所以setprecision(8)設定的是小數點後面的位數,而非全部數字個數。

在用指數形式輸出時,setprecision(n)表示小數位數。

第8行輸出用setiosflags(ios::scientific)來表示指數表示的輸出形式。其有效位數沿用上次的設定值8。

小數位數截短顯示時,進行4舍5入處理。

4.設定值的輸出寬度

除了使用空格來強行控制輸出間隔外,還可以用setw(n)控制符。如果一個值需要比setw(n)確定的字元數更多的字元,則該值將使用它所需要的所有字元。例如:

float amount=3.14159;

cout <

其執行結果為:3.14159。它並不按4位寬度,而是按實際寬度輸出。

如果一個值的字元數比setw(n)確定的字元個數更少,則在數字字元前顯示空白,不同於其他控制符,setw(n)僅僅影響下一個數值輸出,換句話說,使用setw設定的間隔方式並不保留其效力。例如:

cout<

<<10

<<20<

執行結果為:

-------1020

執行結果中的下橫線表示空格。整數20並沒有按寬度8輸出。setw()的預設值為寬度0,即setw(0),意思是按輸出數值的表示寬度輸出, 所以20就緊挨10了。

格式化C盤的問題,格式化C盤的後果是什麼

在format後加命令引數後,執行不同的格式化命令,詳細說明 q 快速格式化磁碟。這個命令只格式化磁碟的檔案分配表,檔案內容沒有受到損壞,所以使用這個引數格式化磁碟以後,裡面的檔案基本上是能夠恢復的。另外,一般的時候推薦大家使用這個引數,1 因為格式化速度快 2 減少對磁碟的磨損。u 無條件格式化。...

怎麼把C盤格式化,電腦C盤怎麼格式化?

準備好一張microsoft windows xp的安裝光碟.要有可以在dos下啟動並且進行安裝功能的光碟.2.將你的電腦設定成 光碟機啟動 也就是把電腦的第一啟動項設定成 cd rom 3.啟動電腦,將安裝光碟放入到光碟機當中.並且選擇 光碟機啟動 4.之後安裝光碟將對你的電腦硬體進行掃描.已做好...

如何格式化Ntfs格式的c盤,如何格式化Ntfs格式的c盤

如果c盤是系統盤的話 只能在dos下格式化,不過不是ntfs的。或者用xp安裝光碟啟動,選擇安裝xp,之前有讓你選擇格式化選項,選擇格式化為ntfs的就可以了 不要在dos下格式化!因為它不認ntfs!可以找個xp系統盤!光碟機啟動后里面有個選項就是格式化c!或者用pq或者dm來格式化!pq還能檢查...