6

我正在使用 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 < 0 并处理它,还是我可以安全地假设不会有问题?

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

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

4

4 回答 4

6

从 c99 标准:

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

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

于 2010-06-01T09:11:00.703 回答
2

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

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

否则,它没有理由失败。

于 2010-06-01T08:53:12.360 回答
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 - 使用带有 int 的 %s 格式说明符的示例,32 位示例:

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

sprintf(tmp, "%s", pdq);
于 2010-06-06T16:25:34.277 回答
2

我相信还有另一种情况 snprintf() 不能成功。在 POSIX 或当前的 Linux 手册页中似乎没有提到它。

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

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

于 2018-03-08T16:06:34.283 回答