c語言snprintf函數(shù)的用法詳解
snprintf()函數(shù)是一種格式化函數(shù),用于將格式化的字符串存儲(chǔ)到一個(gè)字符數(shù)組中,并且有一個(gè)參數(shù)用來限制輸出的最大字符數(shù)。
語法:
int snprintf ( char * s, size_t n, const char * format, … );
參數(shù):
- s:指向要存儲(chǔ)字符串(由format參數(shù)格式化)的字符數(shù)組。
- n:指定存儲(chǔ)字符串的最大字符數(shù)(不包括NULL結(jié)尾)。
- format:是格式字符串,用于格式化輸出字符串。
返回值:
- 該函數(shù)返回實(shí)際寫入的字符數(shù)(不包括NULL結(jié)尾)。
snprintf()函數(shù)的最大特點(diǎn)是它可以防止由于格式化字符串太長(zhǎng)而導(dǎo)致的緩沖區(qū)溢出,它可以自動(dòng)截?cái)嘧址?,以確保不會(huì)超出緩沖區(qū)限制。
實(shí)例:
例如,下面的示例使用snprintf()函數(shù)將字符串“Hello world”存儲(chǔ)到一個(gè)大小為10個(gè)字符的字符數(shù)組中:
#include <stdio.h> int main( ) { char str[10]; snprintf(str, 10, "Hello world"); printf("%s\n", str); return 0; }
輸出:
Hello wor
這里面包含一個(gè)’\0’
特別注意
1. 無論何時(shí)一定會(huì)在字符串末尾添加'\0' 字符串結(jié)束符。
- 當(dāng)字符串長(zhǎng)度小于size時(shí),會(huì)直接在字符串的末尾添加'\0';
- 當(dāng)字符串長(zhǎng)度等于size時(shí),會(huì)取前size-1個(gè)字符,并在末尾添加‘\0’(即:加上'\0'后,一共size個(gè)字符);
- 當(dāng)字符串長(zhǎng)度大于size時(shí),只取前size-1個(gè)字符,并在末尾添加'\0'(即:加上'\0'一共size個(gè)字符);
綜上:snprintf不僅一定會(huì)自動(dòng)在字符串末尾添加'\0',而且一定會(huì)尊重指定長(zhǎng)度size的大小,不會(huì)超過該長(zhǎng)度(算上自動(dòng)在末尾增加的'\0')。所以從這一點(diǎn)來講,使用snprintf是相對(duì)比較安全的,不用擔(dān)心會(huì)出現(xiàn)overflow的情況。
NOTE:這一點(diǎn)上,snprintf與strncpy是有區(qū)別的。strncpy雖然也會(huì)指定目的內(nèi)存的大小,但是當(dāng)源字符串長(zhǎng)度大于指定的內(nèi)存大小時(shí),strncpy雖然在達(dá)到指定大小后會(huì)停止copy,但是并不會(huì)在末尾自動(dòng)添加'\0'。這樣,在訪問字符串時(shí),有可能出現(xiàn)overflow的情況,因?yàn)槟┪矝]有字符串結(jié)束符'\0'。
思考:
(1)當(dāng)目的內(nèi)存實(shí)際長(zhǎng)度為N1,但是在使用snprintf時(shí)指定的實(shí)際size(第二個(gè)參數(shù))為N2, 且N2<N1,可能會(huì)出現(xiàn)什么情況?
(2)如果N2>N1,又可能出現(xiàn)什么情況?
2. 特別小心返回值。
- 當(dāng)出現(xiàn)錯(cuò)誤時(shí),會(huì)返回負(fù)值;
- 當(dāng)字符串長(zhǎng)度小于size時(shí),返回打印到目的內(nèi)存的實(shí)際字符串長(zhǎng)度(不包括'\0');
- 當(dāng)字符串長(zhǎng)度大于等于size時(shí),盡管字符串會(huì)被截?cái)啵ㄖ挥衧ize-1個(gè)字符串被打印到目的內(nèi)存),但是返回值卻會(huì)返回源字符串的實(shí)際長(zhǎng)度(即假設(shè)目的內(nèi)存無限大,總是能寫下源字符串)。
綜上:snprintf的返回值可能大于或等于指定的size,這時(shí)候說明目的內(nèi)存不夠大,源字符串被截?cái)?,需要小心處理,這是否是期望發(fā)生的情形。
NOTE:有一些寫法會(huì)利用snprintf的這個(gè)特點(diǎn)來確定合適的目的內(nèi)存大小,例如:
const char *fmt = "sqrt(2) = %f"; char * buf; int sz = snprintf(NULL, 0, fmt, sqrt(2)); buf = (char *)malloc(sz+1); // +1 for append '\0' snprintf(buf, sz+1, fmt, sqrt(2));
總結(jié)
到此這篇關(guān)于c語言snprintf函數(shù)用法的文章就介紹到這了,更多相關(guān)c語言snprintf函數(shù)用法內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Qt動(dòng)態(tài)庫調(diào)用宿主進(jìn)程中的對(duì)象方法純虛函數(shù)使用
這篇文章主要為大家介紹了Qt動(dòng)態(tài)庫調(diào)用宿主進(jìn)程中的對(duì)象方法純虛函數(shù)使用,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-08-08VC中使用ADO開發(fā)數(shù)據(jù)庫應(yīng)用程序簡(jiǎn)明教程
這篇文章主要介紹了VC中使用ADO開發(fā)數(shù)據(jù)庫應(yīng)用程序的方法,結(jié)合實(shí)例形式詳細(xì)講述了ADO的原理及VC使用ADO開發(fā)數(shù)據(jù)庫應(yīng)用程序的相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2016-06-06C++實(shí)現(xiàn)浮點(diǎn)數(shù)精確加法
這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)浮點(diǎn)數(shù)精確加法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-05-05