2010-06-01 94 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