Действительно ли возможно читать в строке неизвестного размера в C, не имея необходимость помещать его в предварительно выделенный буфер фиксированной длины?

Действительно ли возможно читать в строке в C, не выделяя массив фиксированного размера заранее?

Каждый раз я объявляю массив символов некоторого фиксированного размера, я чувствую, что делаю его неправильно. Я всегда беру предположение в том, что я думаю, был бы максимум для моего варианта использования, но это не всегда легко.

Кроме того, мне не нравится идея наличия меньшей строки, находящейся в большем контейнере. Это не чувствует себя хорошо.

Я пропускаю что-то? Есть ли некоторый другой способ, которым я должен делать это?

9
задан Daonkoyd 3 March 2010 в 17:24
поделиться

6 ответов

Вы можете использовать функцию публичного домена Чака Фалконера ggets для управления буфером и перераспределения за вас: http://cbfalconer.home.att.net/download/index.htm

Изменить: Веб-сайт Чака Фалконера больше не доступен. archive.org все еще имеет копию , и я тоже размещаю копию .

0
ответ дан 4 December 2019 в 15:15
поделиться

Когда вы говорите «заранее», вы имеете в виду во время выполнения или во время компиляции? Во время компиляции вы делаете это:

char str[1000];

во время выполнения вы делаете это:

char *str = new char[size];

Они только так чтобы получить точно правильный размер, нужно знать, сколько символов вы собираетесь прочитать. Если вы читаете из файла, вы можете найти ближайший перевод строки (или какое-либо другое условие), и тогда вы точно знаете, насколько велик массив должно быть. то есть:

int numChars = computeNeededSpace(someFileHandle);
char *readBuffer = new char[numChars];
fread(someFileHandle, readBuffer, numChars);  //probly wrong parameter order

Другого способа сделать это нет. Представьте себя с точки зрения программы: как можно узнать, сколько клавиш собирается нажать пользователь? Лучшее, что вы можете сделать, - это ограничить пользователя или любой другой ввод.

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

РЕДАКТИРОВАТЬ: В большинстве языков есть классы строк / буферов ввода, которые скрывают это от вас.

3
ответ дан 4 December 2019 в 15:15
поделиться

Вы должны выделить фиксированный буфер. Если он станет маленьким, то realloc () увеличьте его размер и продолжите.

2
ответ дан 4 December 2019 в 15:15
поделиться

В момент, когда вы читаете данные, ваш буфер будет иметь фиксированный размер - это неизбежно.

Что вы можете сделать, так это прочитать данные с помощью fgets и проверить, является ли последний символ '\ n' (или вы достигли конца файла), а если нет, realloc ваш буфер и прочитайте больше.

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

7
ответ дан 4 December 2019 в 15:15
поделиться

Невозможно определить длину строки, пока вы ее не прочитаете, поэтому чтение ее в буфер фиксированного размера - ваш единственный выбор.

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

Возможно, самый простой способ справиться с этой дилеммой - определить максимальную длину для определенной входной строки ( #define - помогает константа для этого значения). Используйте буфер этого заранее определенного размера всякий раз, когда вы читаете строку, но обязательно используйте форму строковых команд strncpy () , чтобы вы могли указать максимальное количество символов для чтения. Некоторые часто используемые типы строк (например, имена файлов или пути) могут иметь максимальную длину, определяемую системой.

Нет ничего «неправильного» в объявлении массива фиксированного размера, если вы его правильно используете (выполняйте правильную проверку границ и обрабатывайте случай, когда ввод будет переполнять массив). Это может привести к выделению неиспользуемой памяти, но, к сожалению, язык C не дает нам много работы, когда дело касается строк.

1
ответ дан 4 December 2019 в 15:15
поделиться

Существует концепция String Ropes , которая позволяет создавать деревья с буферами фиксированного размера. У вас все еще должны быть буферы фиксированного размера, от этого никуда не деться, но это довольно изящный способ динамического создания строк.

0
ответ дан 4 December 2019 в 15:15
поделиться
Другие вопросы по тегам:

Похожие вопросы: