何时以及为什么sprintf会失败?

时间:2010-06-01 08:50:15

标签: c++ c printf widestring

我正在使用swprintf将字符串构建到缓冲区(使用循环等)。

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';

如果在测试过程中断言从不命中,我可以确定它永远不会出现在实时代码中吗?也就是说,我是否需要检查nWritten&lt; 0并处理,或者我可以安全地假设不存在问题吗?

在哪种情况下可以返回-1?文档或多或少只是说明“如果函数失败”。在一个地方,我已经读过,如果它不能匹配参数(即格式化字符串与varargs),它将会失败,但这并不让我担心。

在这种情况下,我也不担心缓冲区溢出 - 我知道缓冲区足够大。

4 个答案:

答案 0 :(得分:4)

来自c99标准:

  

sprintf函数返回在数组中写入的字符数,不包括终止空字符,如果发生编码错误,则返回负值。

这通常只发生在多字节和宽字符集字符集中。

答案 1 :(得分:2)

例如,错误的格式字符串可能会失败,在您的情况下不会发生。

如果缓冲区不够大,可能会。

否则,没有理由失败。

答案 2 :(得分:2)

在UNIX中,它可能会失败:

 EILSEQ
       A wide-character code that does not  correspond  to  a
       valid character has been detected.

 EINVAL
       There are insufficient arguments.

EILSEQ已被提及。

当格​​式说明符与数据不匹配时,SIGSEGV也可能失败 - 例如使用%s格式说明符和int,32位示例:

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

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

答案 3 :(得分:2)

我相信还有另一种情况,即snprintf()无法成功。它似乎没有在POSIX或当前的Linux联机帮助页中提及。

  

成功完成后,snprintf()函数将返回写入s的字节数,其中n已足够大,不包括终止空字节。

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