Выделение массива неизвестного размера - PullRequest
2 голосов
/ 01 апреля 2012

Контекст: Я пытаюсь создать программу, которая будет принимать текст в качестве входных данных и сохранять его в массиве символов.Тогда я бы напечатал каждый элемент массива в виде десятичного числа.Например, «Hello World» будет преобразован в 72, 101 и т. Д. Я бы использовал это как быстрый конвертер ASCII2DEC.Я знаю, что есть онлайн-конвертеры, но я пытаюсь сделать это самостоятельно.

Проблема: как мне выделить массив, размер которого неизвестен во время компиляции, и сделать его точно таким же размером, как и текст, который я ввожу?Поэтому, когда я вхожу в «Hello World», он динамически создает массив с точным размером, необходимым для хранения только «Hello World».Я искал в Интернете, но не смог найти ничего, что я мог бы использовать.

Ответы [ 4 ]

1 голос
/ 01 апреля 2012

Я вижу, что вы используете C. Вы можете сделать что-то вроде этого:

 #define INC_SIZE 10

 char *buf = (char*) malloc(INC_SIZE),*temp;
 int size = INC_SIZE,len = 0;
 char c;

 while ((c = getchar()) != '\n') { // I assume you want to read a line of input
   if (len == size) {
     size += INC_SIZE;
     temp = (char*) realloc(buf,size);
     if (temp == NULL) {
       // not enough memory probably, handle it yourself
     }
     buf = temp;
   }
   buf[len++] = c;
 }
 // done, note that the character array has no '\0' terminator and the length is represented by `len` variable
0 голосов
/ 01 апреля 2012

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

Переменные, которые вы объявляете в функции, хранятся в стеке .Это хорошо и эффективно, очищается при выходе из функции и т. Д. Единственная проблема заключается в том, что размер слота стека для каждой функции фиксирован и не может изменяться во время работы функции.

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

При выделении кучи вы должны знать размер при alloc время, но это лучше, чем хранить его в фиксированном стековом пространстве, которое невозможно увеличить при необходимости.

Это простая и глупая функция для декодирования строки в ее ASCII-коды с использованием динамически выделяемого буфера:

char* str_to_ascii_codes(char* str)
{
    size_t i;
    size_t str_length = strlen(str);
    char* ascii_codes = malloc(str_length*4+1);
    for(i = 0; i<str_length; i++)
        snprintf(ascii_codes+i*4, 5, "%03d ", str[i]);
    return ascii_codes;
}

Редактировать: Вы упомянули в комментарии, желая получить буфер правильно.Я обрезал углы с помощью приведенного выше примера, сделав каждую запись в строке известной длины и не обрезая лишний пробел в результате.Это более умная версия, которая устраняет обе эти проблемы:

char* str_to_ascii_codes(char* str)
{
    size_t i;
    int written;
    size_t str_length = strlen(str), ascii_codes_length = 0;
    char* ascii_codes = malloc(str_length*4+1);
    for(i = 0; i<str_length; i++)
    {
        snprintf(ascii_codes+ascii_codes_length, 5, "%d %n", str[i], &written);
        ascii_codes_length = ascii_codes_length + written;
    }
    /* This is intentionally one byte short, to trim the trailing space char */
    ascii_codes = realloc(ascii_codes, ascii_codes_length);
    /* Add new end-of-string marker */
    ascii_codes[ascii_codes_length-1] = '\0';
    return ascii_codes;
}
0 голосов
/ 01 апреля 2012

если вы используете язык cpp, вы можете использовать строку для хранения вводимых символов и доступа к символу с помощью оператора [], например, следующих кодов:

std::string input;
cin >> input; 
0 голосов
/ 01 апреля 2012

Как правило, в таких средах, как ПК, где нет больших ограничений памяти, я бы просто динамически выделял (зависит от языка) массив / строку / что угодно, скажем, 64 КБ и сохранял индекс / указатель / что угодно для текущая конечная точка плюс один - т.е. следующий индекс / место для размещения новых данных.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...