Когда и почему может произойти сбой sprintf? - PullRequest
4 голосов
/ 01 июня 2010

Я использую 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';

Если во время тестирования assert никогда не срабатывает, могу ли я быть уверен, что оно никогда не попадет в живой код? То есть мне нужно проверить, если nWritten <0, и обработать это, или я могу смело предположить, что проблемы не будет? </p>

При каких обстоятельствах он может вернуть -1? В документации более или менее просто говорится «Если функция не работает». В одном месте я читал, что он потерпит неудачу, если не сможет сопоставить аргументы (то есть строку форматирования с переменными), но это меня не беспокоит.

Я также не беспокоюсь о переполнении буфера в этом случае - я знаю, что буфер достаточно большой.

Ответы [ 4 ]

4 голосов
/ 01 июня 2010

Из стандарта C99:

Функция sprintf возвращает количество символов, записанных в массиве, не считая завершающий нулевой символ, или отрицательное значение в случае ошибки кодирования.

Обычно это происходит только с функциями набора многобайтовых и широких символов.

2 голосов
/ 08 марта 2018

Я полагаю, что есть еще один случай, когда snprintf () не может быть успешным. Он не упоминается ни в POSIX, ни в текущей справочной странице по Linux.

После успешного завершения функция snprintf () должна вернуть число байтов, которые были бы записаны в s, если бы n было достаточно большим, за исключением завершающего нулевого байта.

snprintf () возвращает int. Но входная строка может быть больше, чем INT_MAX.

2 голосов
/ 06 июня 2010

В 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 с 32-битным примером int:

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

sprintf(tmp, "%s", pdq);
2 голосов
/ 01 июня 2010

Может произойти сбой, например, с неверной форматной строкой, чего не может быть в вашем случае.

Если буфер недостаточно велик, возможно.

В противном случае, нет причин для его сбоя.

...