Проблема именно в том, о чем говорит вам ваш компилятор; вам не разрешено инициализировать VLA. Зак дал очевидное решение в комментариях: удалить инициализацию. В этом ответе вы найдете рабочие примеры, некоторые из которых разрешают инициализацию, а другие — нет. Вы найдете больше информации об этом в комментариях. Следующие примеры упорядочены от наиболее разумного (IMHO) к наименее разумному (который включает использование malloc
) для выделения памяти для последовательностей десятичных цифр, представляющих числа.
Я предлагаю использовать тот же трюк, чтобы определить, сколько байтов необходимо для хранения значения int
в виде десятичных цифр, которые вы использовали бы для восьмеричного: разделите общее количество битов в int
на 3 и добавьте для любого знака и окончания NUL. digit_count
может быть записан как макрос препроцессора следующим образом:
#include <limits.h>
#include <stddef.h>
#include <stdio.h>
#define digit_count(num) (1 /* sign */ \
+ sizeof (num) * CHAR_BIT / 3 /* digits */ \
+ (sizeof (num) * CHAR_BIT % 3 > 0)/* remaining digit */ \
+ 1) /* NUL terminator */
int main(void) {
short short_number = -32767;
int int_number = 32767;
char short_buffer[digit_count(short_number)] = { 0 }; /* initialisation permitted here */
char int_buffer[digit_count(int_number)];
sprintf(short_buffer, "%d", short_number);
sprintf(int_buffer, "%d", int_number);
}
Как вы можете видеть, одно большое преимущество здесь заключается в том, что digit_count
можно использовать для любого типа целого числа без модификации: char
, short
, int
, long
, long long
и соответствующих типов unsigned
.
Один небольшой недостаток по сравнению с этим заключается в том, что вы тратите несколько байтов памяти, особенно для небольших значений, таких как 1
. Во многих случаях простота этого решения более чем компенсирует это; Код, необходимый для подсчета десятичных цифр во время выполнения, будет занимать больше места в памяти, чем тратится здесь.
Если вы готовы отказаться от простоты и универсальности приведенного выше кода и действительно хотите подсчитать количество десятичных цифр, применим совет Зака: удалите инициализацию. Вот пример:
#include <stddef.h>
#include <stdio.h>
size_t digit_count(int num) {
return snprintf(NULL, 0, "%d", num) + 1;
}
int main(void) {
int number = 32767;
char buffer[digit_count(number)]; /* Erroneous initialisation removed as per Zacks advice */
sprintf(buffer, "%d", number);
}
В ответ на рекомендации malloc
: Наименее ужасный способ решить эту проблему — избегать ненужного кода (например, вызовов malloc
и позже free
). Если вам не нужно возвращать объект из функции, не используйте malloc
! В противном случае рассмотрите возможность сохранения в буфере, предоставленном вызывающей стороной (через аргументы), чтобы вызывающая сторона могла выбрать, какой тип хранилища использовать. Очень редко это не является подходящей альтернативой использованию malloc
.
Однако, если вы решите использовать для этого malloc
и free
, делайте это наименее ужасным способом. Избегайте приведения типов к возвращаемому значению malloc
и умножения на sizeof (char)
(которое всегда равно 1). Следующий код является примером. Используйте любой из вышеперечисленных методов для расчета длины:
char *buffer = malloc(digit_count(number)); /* Initialisation of malloc bytes not possible */
sprintf(buffer, "%d", number);
... и не забудьте free(buffer);
, когда закончите.
person
autistic
schedule
07.06.2013
= ""
.snprintf
заранее не волнует, что находится в его выходном буфере. - person zwol   schedule 07.06.2013gcc prog.c -std=c99
или заменить новую версию gcc - person BLUEPIXY   schedule 07.06.2013char fileSizeStr[5] = "";
или использование malloc. - person anairinac   schedule 07.06.2013malloc
. - person autistic   schedule 07.06.2013= ""
? - person zwol   schedule 07.06.2013char buffer[getDigits(number)+1];
он вернул это:Kvothe cripto-tdes-actual # ./zack 27 -> Number: 27
. Я изменю свой выбранный ответ на одно предоставленное поведение @undefined, потому что оно использует ваше, оно наиболее полное, дало альтернативные getDigits (включая макрос), дало довольно подробное объяснение того, почему использование malloc в этом случае было ненужным, и рекомендуется избегать приведения типов и умножения на 1. - person anairinac   schedule 10.06.2013