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)是它可以防止由于格式化字符串太長而導(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)字符串長度小于size時(shí),會(huì)直接在字符串的末尾添加'\0';
- 當(dāng)字符串長度等于size時(shí),會(huì)取前size-1個(gè)字符,并在末尾添加‘\0’(即:加上'\0'后,一共size個(gè)字符);
- 當(dāng)字符串長度大于size時(shí),只取前size-1個(gè)字符,并在末尾添加'\0'(即:加上'\0'一共size個(gè)字符);
綜上:snprintf不僅一定會(huì)自動(dòng)在字符串末尾添加'\0',而且一定會(huì)尊重指定長度size的大小,不會(huì)超過該長度(算上自動(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)源字符串長度大于指定的內(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í)際長度為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)字符串長度小于size時(shí),返回打印到目的內(nèi)存的實(shí)際字符串長度(不包括'\0');
- 當(dāng)字符串長度大于等于size時(shí),盡管字符串會(huì)被截?cái)啵ㄖ挥衧ize-1個(gè)字符串被打印到目的內(nèi)存),但是返回值卻會(huì)返回源字符串的實(shí)際長度(即假設(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)文章
C語言實(shí)現(xiàn)醫(yī)院管理系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了C語言實(shí)現(xiàn)醫(yī)院管理系統(tǒng),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-12-12
C語言中獲取和改變目錄的相關(guān)函數(shù)總結(jié)
這篇文章主要介紹了C語言中獲取和改變目錄的相關(guān)函數(shù)總結(jié),包括getcwd()函數(shù)和chdir()函數(shù)以及chroot()函數(shù)的使用方法,需要的朋友可以參考下2015-09-09
C語言中的數(shù)組指針數(shù)組與函數(shù)指針數(shù)組
數(shù)組指針數(shù)組和函數(shù)指針數(shù)組是兩個(gè)強(qiáng)大但容易混淆的概念,下面就來介紹一下C語言中的數(shù)組指針數(shù)組與函數(shù)指針數(shù)組的區(qū)別,具有一定的參考價(jià)值,感興趣的可以了解一下2025-06-06
C++/STL實(shí)現(xiàn)判斷平面內(nèi)兩條線段的位置關(guān)系代碼示例
這篇文章主要介紹了C++/STL實(shí)現(xiàn)判斷平面內(nèi)兩條線段的位置關(guān)系代碼示例,具有一定參考價(jià)值,需要的朋友可以了解下。2017-11-11
淺析C++調(diào)用Java的Jar包(帶參數(shù))問題
這篇文章主要介紹了C++調(diào)用Java的Jar包(帶參數(shù))問題,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-11-11
c語言實(shí)現(xiàn)php的trim標(biāo)簽
本文給大家介紹的是使用C語言實(shí)現(xiàn)php的trim標(biāo)簽功能的代碼,非常的實(shí)用,其主要作用是清除字符串開頭結(jié)尾除空白,有需要的小伙伴可以參考下。2016-01-01
C++類與對(duì)象深入之靜態(tài)成員與友元及內(nèi)部類詳解
朋友們好,這篇播客我們繼續(xù)C++的初階學(xué)習(xí),現(xiàn)在對(duì)我們對(duì)C++的靜態(tài)成員,友元,內(nèi)部類知識(shí)點(diǎn)做出總結(jié),整理出來一篇博客供我們一起復(fù)習(xí)和學(xué)習(xí),如果文章中有理解不當(dāng)?shù)牡胤?還希望朋友們?cè)谠u(píng)論區(qū)指出,我們相互學(xué)習(xí),共同進(jìn)步2022-06-06

