Если вы работаете на платформе, которая поддерживает POSIX или C99, вы сможете использовать snprintf
для вычисления размера буфера, который вам понадобится. snprintf
принимает параметр, указывающий размер буфера, который вы передаете; если размер строки будет превышать размер этого буфера, он усекает вывод, чтобы поместиться в буфер, и возвращает количество места, которое ему потребовалось бы для размещения всего вывода. Вы можете использовать выходные данные этого, чтобы выделить буфер, который является точным правильным размером. Если вы просто хотите вычислить размер буфера, который вам нужен, вы можете передать NULL в качестве буфера и размер 0, чтобы вычислить, сколько места вам нужно.
int size = snprintf(NULL, 0, "%.20g", x);
char *buf = malloc(size + 1); // Need the + 1 for a terminating null character
snprintf(buf, size + 1, "%.20g", x);
Не забудьте free(buf)
после того, как вы его использовали, чтобы избежать утечек памяти.
Проблема в том, что он не будет работать в Visual Studio, которая все еще не поддерживает C99. Хотя они имеют что-то вроде snprintf
, если переданный буфер слишком мал, он не возвращает необходимый размер, а вместо этого возвращает -1
, что совершенно бесполезно (и он не принимает NULL
как буфер, даже с длиной 0
.
Если вы не возражаете против усечения, вы можете просто использовать snprintf
с буфером фиксированного размера и быть уверенным, что вы не переполните его:
char buf[30];
snprintf(buf, sizeof(buf), "%.20g", x);
Убедитесь, что вы проверили документы своей платформы на snprintf
; в частности, некоторые платформы могут не добавлять завершающий нуль в конец строки, если строка обрезана, поэтому вам может потребоваться сделать это самостоятельно.