2010-06-01 89 views
4

我正在使用swprintf建立一個字符串到緩衝區(使用循環等)。何時以及爲什麼sprintf失敗?

const int MaxStringLengthPerCharacter = 10 + 1; 
wchar_t* pTmp = pBuffer; 
for (size_t i = 0; i < nNumPlayers ; ++i) 
{ 
    const int nPlayerId = GetPlayer(i); 
    const int nWritten = swprintf(pTmp, MaxStringLengthPerCharacter, TEXT("%d,"), nPlayerId); 
    assert(nWritten >= 0); 
    pTmp += nWritten; 
} 

*pTaskPlayers = '\0'; 

如果在測試過程中assert從未命中,我可以確定它將永遠不會在實時代碼中命中嗎?也就是說,我是否需要檢查並處理該問題,還是可以安全地假定不存在問題?

在哪些情況下可以返回-1?文檔或多或少只是陳述「如果功能失敗」。在我讀過的一個地方,如果它不能匹配參數(即可變參數的格式化字符串),但它不會讓我擔心,它會失敗。

我也不擔心緩衝區溢出在這種情況下 - 我知道緩衝區足夠大。

+3

由於這是C++的標籤,你有沒有考慮過使用stringstreams?更方便。 – 2010-06-01 08:55:15

+0

代碼的性能很重要,這就是爲什麼我已經使用了一個預分配的緩衝區字符串,我只是將它複製到這個字符串中。我假設stringstreams可能每次都會執行一些內存分配? – Srekel 2010-06-21 08:42:44

回答

4

C99標準:

sprintf函數返回寫入所述陣列中,不計算終止空字符,或負的值,如果發生編碼錯誤的字符數。

這通常只發生在多字節和寬字符字符集函數中。

+0

這完全是合適的,因爲OP實際上使用了寬字符版本'swprintf()'。 – caf 2010-06-01 10:31:44

+0

是的,但不應該是一個問題,只要我知道我不使用任何「陌生」字符,我相信。 – Srekel 2010-06-01 14:29:13

2

它可能會失敗,錯誤的格式字符串,例如,你的情況不會發生。

如果緩衝區不夠大,可能會。

否則,沒有理由失敗。

2

在UNIX中,它可能會失敗:

​​3210

EILSEQ已經提到。

它也可能失敗,SIGSEGV,當格式說明不將數據匹配 - 使用%s格式指定符與一個int例如32位例如:

int pdq=0xffffffff; 
char tmp[32]={0x0}; 

sprintf(tmp, "%s", pdq); 
2

相信有另一種情況,其中snprintf()不能成功。它似乎沒有在POSIX或當前的Linux聯機幫助頁面中提及。

成功完成後,snprintf()函數將返回將被寫入的字節數,如果n足夠大,排除終止空字節。

snprintf()返回int。但輸入字符串可能大於INT_MAX

相關問題