1. 程式人生 > >sprintf,sprintf_s,_snprintf和_snprintf_s之間的區別

sprintf,sprintf_s,_snprintf和_snprintf_s之間的區別

sprintf與sprintf_s區別

函式原型:
int sprintf(char *buffer,const char *format [,argument] ...);

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

1、sprintf_s對format 中的格式化的字元的有效性進行了檢查,而sprintf僅僅檢查format 或者緩衝區是否是空指標。如果有錯誤則返回相應的錯誤程式碼。
2、sprintf_s引數sizeOfBuffer是接收格式化字串的緩衝區的大小。如果,格式化字串過大,則sprintf_s會返回一個空string和設定無效引數控制代碼為啟用。

3、sprintf_s將格式化字串存到緩衝區,並在下一個位置填充Null後將格式化字串未佔用的緩衝區(Null之後的Buffer)全部填充為-3,而sprintf卻不會填充而是保持緩衝區中未佔用的儲存位置上的資料。

sprintf_s,_snprintf與_snprintf_s區別

函式原型:
int sprintf_s(char *buffer,size_t sizeOfBuffer,const char *format [,argument] ... );
int _snprintf(char *buffer,size_t count,const char *format [,argument] ... );

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

從sprintf與sprintf_s區別可以知道,如果應該輸出的字串的大小已經達到了sizeOfBuffer,那麼就溢位了。溢位的情況下,sprintf_s函式把這當做一個錯誤,會把buffer緩衝區置為一個空字串""。而count引數的作用是,輸出的字串就算超過緩衝區長度,仍然會有輸出,輸出字串被截斷到count大小,在這個大小的字串後面加null-teminate。

這裡比較引人注目的是,_snprintf_s為什麼在sizeOfBuffer的基礎上,還要多加一個count?count似乎是用來控制理想的寬度的。如果得到的字串超過了count,於是會被截斷到count的長度後面再加一個null-teminate。當然,更高優先順序的應該是sizeOfBuffer,必須不超過這個大小。當然,如果count被設定成和sizeOfBuffer同樣大,或者不合理的更大,那麼這個count引數就失去了意義。這時候,如果輸出字串將要達到或者超過sizeOfBuffer,一樣導致一個錯誤,輸出緩衝區被置為空字串。因此,如果希望緩衝區被儘量利用,可以把count引數置為_TRUNCATE,這樣的情況下,實際上效果相當於是將count設定為sizeOfBuffer - 1。


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

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

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

所以,在C++中使用這類函式,還是應該儘可能的使用_snprintf_s才好。