Создать массив целых чисел, используя цифры в качестве размера

Я пытаюсь создать массив символов в C, чтобы заполнить его цифрами int, но int может иметь любое количество цифр.

м, используя созданную функцию под названиемgetDigits(int num), который возвращает количество цифр, которое имеет int.

char buffer[getDigits(number)] = "";
snprintf(buffer, sizeof(buffer),"%d",number);

но когда я компилирую с помощью gcc, он возвращает: I '

error: variable-sized object may not be initialized

мы все перепробовали. Когда я объявляю это какchar fileSizeStr[5] = "";, оно работает. Я вижу, что проблема возрастает, когда я пытаюсь динамически объявить размер буфера, но мне бы очень хотелось узнать, есть ли способ добиться этого.

 autistic09 июн. 2013 г., 18:59
Давайте посмотрим, сможет ли кто-нибудь придумать лучший ответ, чем я дал ...
 zwol07 июн. 2013 г., 03:02
@anairinac Что именно произошло, когда вы удалили?= ""
 anairinac07 июн. 2013 г., 02:43
Спасибо, с помощью malloc работал отлично!
 anairinac09 июн. 2013 г., 22:12
@ Зак, я правда нене понимаю, почему это не такТ работал раньше, но ваше решение работает сейчас. Без инициализации и изменения объявления буфера наchar buffer[getDigits(number)+1];Вернул это:Kvothe cripto-tdes-actual # ./zack 27 -> Number: 27, Я'Я изменю свой выбранный ответ на предоставленный один @undefined, потому что он использует ваш, он 's самый полный, дал альтернативные getDigits (включая макрос), дал довольно подробное объяснение того, почему использование malloc в этом случае было ненужным, и посоветовал избегать типов типов и умножения на 1.
 Duck07 июн. 2013 г., 02:29
malloc буфер.
 anairinac07 июн. 2013 г., 02:45
@Zack Я пробовал это раньше и использовал sprintf. Но на данный момент только объявление буфера, какchar fileSizeStr[5] = ""; или с помощью malloc работал.
 BLUEPIXY07 июн. 2013 г., 02:38
gcc prog.c -std=c99 или замените новую версию gcc
 zwol07 июн. 2013 г., 02:31
Попробуйте удалить.= ""snprintf Безразлично»все равно, чтозаранее в выходном буфере.
 BLUEPIXY07 июн. 2013 г., 02:30
используйте компилятор c99 или используйте malloc
 autistic07 июн. 2013 г., 02:51
@ Зак Напиши ответ ...это шуткаmalloc будет предложено здесь.

Ответы на вопрос(5)

Решение Вопроса

вы'не разрешено инициализировать VLA. Зак дал очевидное решение в комментариях: уберите инициализацию. Вы'В этом ответе вы найдете рабочие примеры, некоторые из которых разрешают инициализацию, а другие - нет.т. Вы'Вы найдете больше информации об этом в комментариях. Следующие примеры упорядочены от наиболее разумных (ИМХО) к наименее разумным (которые включают использованиеmalloc) для выделения памяти для последовательностей десятичных цифр, представляющих числа.

Я предлагаю использовать тот же трюк, чтобы определить, сколько байтов необходимо для храненияint значение в виде десятичных цифр, как выd использовать для восьмеричного: разделите общее количество бит в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);
}
</stdio.h></stddef.h></limits.h>

Как видите, одно из важных преимуществ заключается в том, чтоdigit_count может использоваться для любого типа целого числа без изменений:,,,,charshortintlonglong longи соответствующийunsigned типы.

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

Если ты'Вы готовы отбросить простоту и общие качества приведенного выше кода, и вы действительно хотите посчитать количество десятичных цифр, поэтому совет Zacks: удалите инициализацию. Вот'Вот пример:

#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);
}
</stdio.h></stddef.h>

В ответ наmalloc рекомендации: наименее ужасный способ решить эту проблему - избежать ненужного кода (например,malloc и позжеfree). Если вы нене нужно возвращать объект из функции, тогда нет использоватьmalloc! В противном случае рассмотрите возможность сохранения в буфере, предоставленном вызывающим (через аргументы), чтобы вызывающий мог выбрать, какой тип хранилища использовать. Это'очень редко, что это нет подходящая альтернатива использованию.malloc

Если вы решили использоватьmalloc а такжеfree для этого, однако, сделать это наименее ужасным способом. Избегайте typecasts на возвращаемое значениеmalloc и умножения наsizeof (char) (который всегда 1). Следующий код является примером. Используйте любой из вышеперечисленных методов для расчета длины:

char *buffer = malloc(digit_count(number)); /* Initialisation of malloc bytes not possible */
sprintf(buffer, "%d", number);

... и не надозабытьfree(buffer); когда ты'сделано с этим.

которое не упоминалось, но которое на самом деле проще, чем любое из вышеперечисленного. Существует комбинированная распределенная версия sprintf под названием "asprintf» доступно в Linux и большинстве вариантов BSD. Он определяет необходимый размер, выделяет память и возвращает заполненную строку в первый аргумент.

char * a;
asprintf(&a, "%d", 132);
// use a
free(a);

Использование выделенного массива стека, безусловно, устраняет необходимость в свободном доступе, но это полностью устраняет необходимость когда-либо отдельно вычислять размер.

 M.M18 дек. 2015 г., 11:36
примечание: в системах безasprintf, используя C99 это 'легко накатить свой собственный, используя два вызоваsnprintf

malloc выделить динамический объем памяти.

Инициализация, которую вы сделали, разрешена, только если размер известен во время компиляции.

 anairinac07 июн. 2013 г., 02:42
Спасибо! Я могу'Не думаю, что я полностью забыл использовать malloc.
 John07 июн. 2013 г., 02:44
Вы'Добро пожаловать Другие ответы имеют C примеров.

 char* buffer =(char *)malloc(getDigits(number)*sizeof(char));

malloc и calloc используются для динамического распределения.

 autistic07 июн. 2013 г., 04:39
... и этот вопрос помечен [c], а не [c ++] ...
 autistic07 июн. 2013 г., 02:55
1. Не делайТ бросил Маллок. 2. Нет смысла умножать наsizeof (char) так какsizeof (char) являетсявсегда 1 в С.
 Rafael Azevedo07 июн. 2013 г., 03:12
гул, интересно. По тому, что я только что искал, в C мы действительно нев этом случае надо делать слепки. Но программы на С ++ мы делаем .. Спасибо за информацию!

ниже может помочь

char* buffer;
buffer = (char*)malloc(number * sizeof(char));
 NonStatic07 июн. 2013 г., 03:09
почему бы не бросить malloc? Я думаю, что есть только способ выделить память в старом C.
 NonStatic07 июн. 2013 г., 03:17
@ NigelHarper, я думаю, что я написал, приведение возвращаемого значения.
 NonStatic07 июн. 2013 г., 08:04
@ NigelHarper, я понял твою точку зрения. Спасибо!
 Nigel Harper07 июн. 2013 г., 03:21
@mmsc Да, тыприведение возвращаемого значения malloc, и вы не должныт по причинам, изложенным в ответе, который я связал.
 autistic07 июн. 2013 г., 02:54
1. Не делайТ бросил Маллок. 2. Нет смысла умножать наsizeof (char) так какsizeof (char) являетсявсегда 1 в С.

Ваш ответ на вопрос