Количество фактически используемых символов, очевидно, зависит от значения: если time_stamp_for_file_name
равно 0, то на самом деле нужно 2 байта. Если есть сомнения, вы можете использовать snprintf
, который говорит вам, сколько места вам нужно:
int len = snprinf(0, 0, "%ld", (long)time_stamp_for_file_name) + 1;
char *tmp = malloc(len);
if (tmp == 0) { /* handle error */ }
snprintf(tmp, len, "%ld", (long)time_stamp_for_file_name);
Остерегайтесь реализаций, где snprintf
возвращает -1 для недостаточного пространства, а не для требуемого пространства.
Однако, как говорит Пол Р., вы можете определить фиксированную верхнюю границу, основанную на размере long
вашей реализации. Таким образом вы полностью избегаете динамического размещения. Например:
#define LONG_LEN (((sizeof(long)*CHAR_BIT)/3)+2)
(основываясь на том факте, что log-2 в log 10 больше 3). Это +2 дает вам 1 для знака минус и 1 для того факта, что целочисленное деление округляется в меньшую сторону. Вам понадобится еще 1 для нулевого терминатора.
Или:
#define STRINGIFY(ARG) #ARG
#define EXPAND_AND_STRINGIFY(ARG) STRINGIFY(ARG)
#define VERBOSE_LONG EXPAND_AND_STRINGIFY(LONG_MIN)
#define LONG_LEN sizeof(VERBOSE_LONG)
char tmp[LONG_LEN];
sprintf(tmp, "%ld", (long)time_stamp_for_file_name);
VERBOSE_LONG
может быть немного больше, чем вам нужно. На моем компиляторе это (-2147483647L-1)
. Я не уверен, может ли LONG_MIN
расширяться до чего-то вроде шестнадцатеричного литерала или встроенного компилятора, но если это так, то он может быть слишком коротким, и этот трюк не сработает. Тем не менее, достаточно просто выполнить юнит-тестирование.
Если вы хотите, чтобы жесткая верхняя граница охватывала все возможности стандарта, до определенного предела, вы можете попробовать что-то вроде этого:
#if LONG_MAX <= 2147483647L
#define LONG_LEN 11
#else
#if LONG_MAX <= 4294967295L
#define LONG_LEN 11
#else
#if LONG_MAX <= 8589934591L
... etc, add more clauses as new architectures are
invented with bigger longs
#endif
#endif
#endif
Но я сомневаюсь, что оно того стоит: лучше просто определить его в каком-то заголовке переносимости и настроить вручную для новых платформ.