Немного другой подход:
void zap(char **stmt, char *argument, size_t *stmtBufLen)
{
char *fmt="INSERT INTO test(nazwa, liczba) VALUES ('nowy wpis', '%s')";
/**
* Is our current buffer size (stmtBufLen) big enough to hold the result string?
*/
size_t newStmtLen = strlen(fmt) + strlen(argument) - 2;
if (*stmtBufLen < newStmtLen)
{
/**
* No. Extend the buffer to accomodate the new statement length.
*/
char *tmp = realloc(*stmt, newStmtLen + 1);
if (tmp)
{
*stmt = tmp;
*stmtLen = newStmtLen+1;
}
else
{
/**
* For now, just write an error message to stderr; the statement
* buffer and statement length are left unchanged.
*/
fprintf(stderr, "realloc failed; stmt was not modified\n");
return;
}
}
/**
* Write statement with argument to buffer.
*/
sprintf(*stmt, fmt, argument);
}
int main(void)
{
char *stmtBuffer = NULL;
size_t stmtBufferLen = 0;
...
zap(&stmtBuffer, "foo", &stmtBufferLen);
...
zap(&stmtBuffer, "blurga", &stmtBufferLen);
...
zap(&stmtBuffer, "AReallyLongArgumentName", &stmtBufferLen);
...
zap(&stmtBuffer, "AnEvenLongerRidiculouslyLongArgumentName", &stmtBufferLen);
...
free(stmtBuffer);
return 0;
}
Эта версия использует динамическое распределение памяти для изменения размера буфера по мере необходимости, начиная с указателя буфера NULL (realloc (NULL, size) == malloc (size)). Таким образом, вам не нужно беспокоиться о начале работы с буфером, который «достаточно большой». Единственным недостатком является то, что вы должны помнить об освобождении буфера, когда закончите с ним (я обычно не люблю разделять обязанности по управлению памятью между вызывающим и вызываемым абонентами, как это; если я думал об этом более 10 минут, буду придумывать что нибудь получше).