日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

sprintf_s与_snprintf与_snprintf_s

發布時間:2023/12/10 编程问答 46 豆豆
生活随笔 收集整理的這篇文章主要介紹了 sprintf_s与_snprintf与_snprintf_s 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

MSDN頁面分別如下:

spirntf_s:

http://msdn.microsoft.com/zh-cn/library/ce3zzk1k%28VS.80%29.aspx

_snprintf:

http://msdn.microsoft.com/zh-cn/library/2ts7cx93%28v=VS.90%29.aspx

_snprintf_s:

http://msdn.microsoft.com/zh-cn/library/f30dzcf6.aspx

三個頁面都有自己的例子。。其中后2個的例子比較多內容一些。

?

為免將來頁面失效:

int sprintf_s(
char *buffer,
size_t sizeOfBuffer,
const char *format [,
argument] ...

);

template <size_t size>
int sprintf_s(
char (&buffer)[size],
const char *format [,
argument] ...

); // C++ only

int _snprintf(
char *buffer,
size_t count,
const char *format [,
argument] ...

);

int _snprintf(
char (&buffer)[size],
size_t count,
const char *format [,
argument] ...

); // C++ only

int _snprintf_s(
char *buffer,
size_t sizeOfBuffer,
size_t count,
const char *format [,
argument] ...

);

int _snprintf_s(
char (&buffer)[size],
size_t count,
const char *format [,
argument] ...

); // C++ only

?

呼呼。。內容還挺多。

?

?

這里比較引人注目的是,_snprintf_s為什么在sizeOfBuffer的基礎上,還要多加一個count?

count似乎是用來控制理想的寬度的。

如果得到的字符串超過了count,于是會被截斷到count的長度后面再加一個null-teminate

當然,更高優先級的應該是sizeOfBuffer,必須不超過這個大小。這個就說到點子上了。

?

如果應該輸出的字符串的大小已經達到了sizeOfBuffer,那么就溢出了。溢出的情況下,sprintf_s函數把這當做一個錯誤,會把buffer緩沖區置為一個空字符串""。

而_snprintf_s的好處就是,有了count參數,輸出的字符串就算超過緩沖區長度,仍然會有輸出,輸出字符串被截斷到count大小,在這個大小的字符串后面加null-teminate。

當然,如果count被設置成和sizeOfBuffer同樣大,或者不合理的更大,那么這個count參數就失去了意義。

這時候,如果輸出字符串將要達到或者超過sizeOfBuffer,一樣導致一個錯誤,輸出緩沖區被置為空字符串。

因此,如果希望緩沖區被盡量利用,可以把count參數置為_TRUNCATE,這樣的情況下,實際上效果相當于是將count設置為sizeOfBuffer - 1。

?

?

至于C語言環境下,sprintf_s與_snprintf的對比:

注意到,_snprintf的參數用的是count,而sprintf_s的參數用的是sizeOfBuffer。這很能說明問題。

看下對_snprintf的說明:

Let len be the length of the formatted data string (not including the terminating null). len and count are in bytes for _snprintf, wide characters for _snwprintf.

If len < count, then len characters are stored in buffer, a null-terminator is appended, and len is returned.

If len = count, then len characters are stored in buffer, no null-terminator is appended, and len is returned.

If len > count, then count characters are stored in buffer, no null-terminator is appended, and a negative value is returned.

?

也就是說,_snprintf的count參數明明白白的就是一個count。

如果輸出字符串剛好達到count,由于期待的最大長度就是count,那么輸出字符串肯定要完整,不能截斷。

但是假如字符串緩沖區的大小其實就是count,這怎么辦?MS VCRT的設計者認為,在這種情況下應該把輸出字符串的長度告知調用者,讓調用者來決定是否自己添加null-teminate。

換句話說,調用_snprintf時要注意了,必須檢查_snprintf的返回值,如果返回值不是正數,那么還得注意你的字符串緩沖區并不是null-teminate結尾的。

?

總結來說,sprintf_s在緩沖區不夠大時會失敗,失敗時緩沖區中是一個空字符串。

_snprintf不會失敗,但是必須注意如果緩沖區不夠大,緩沖區的內容將不是null-teminate的,必須自己注意字符串的結束。

_snprintf_s結合了2者的優點,只要count參數設置合理,函數就不會因緩沖區不夠而失敗。

?

但是觀察_snprintf_s的說明,有一個很有趣的內容。

這3族函數中,有失敗情況的2個函數sprintf_s和_snprintf_s中,(再次強調,我這里的失敗的意思是,調用后緩沖區里是一個空字符串),_set_invalid_parameter_handler設置的錯誤處理器,在失敗的情況下會被調用。

?

而截斷的情況下,錯誤處理器并不會被調用。

?

VC的庫開發者總是提供一些怪怪的東西。無論如何,讓代碼更加安全總是符合大家的總體期望的。

另外補充一下,查閱這些字符串安全函數的資料的時候要注意,

對微軟來說,凡是限制字符串復制長度的函數,這些設計者仍然認為是不安全的,因為邏輯上來說,

這些長度參數只是限制了源字符串被復制的長度,而不是目標緩沖區的長度。

也就是說,微軟的這些設計者認為,安全的方式其實是依賴C++的機制,辨認出目標緩沖區的真正大小,以此實現安全的復制。

轉載于:https://www.cnblogs.com/yangxx-1990/p/4877111.html

總結

以上是生活随笔為你收集整理的sprintf_s与_snprintf与_snprintf_s的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。