代码之家  ›  专栏  ›  技术社区  ›  Srekel

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

  •  4
  • Srekel  · 技术社区  · 15 年前

    我正在使用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?文档或多或少只显示“如果函数失败”。在一个地方,我读到如果它不能匹配参数(即格式化字符串到varargs),它将失败,但这并不让我担心。

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

    4 回复  |  直到 7 年前
        1
  •  4
  •   paxdiablo    15 年前

    根据C99标准:

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

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

        2
  •  2
  •   Pavel Radzivilovsky    15 年前

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

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

    否则,就没有理由失败。

        3
  •  2
  •   jim mcnamara    15 年前

    在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);
    
        4
  •  2
  •   sourcejedi    7 年前

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

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

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

    推荐文章