Действительно ли возможно читать в строке в C, не выделяя массив фиксированного размера заранее?
Каждый раз я объявляю массив символов некоторого фиксированного размера, я чувствую, что делаю его неправильно. Я всегда беру предположение в том, что я думаю, был бы максимум для моего варианта использования, но это не всегда легко.
Кроме того, мне не нравится идея наличия меньшей строки, находящейся в большем контейнере. Это не чувствует себя хорошо.
Я пропускаю что-то? Есть ли некоторый другой способ, которым я должен делать это?
Вы можете использовать функцию публичного домена Чака Фалконера ggets
для управления буфером и перераспределения за вас: http://cbfalconer.home.att.net/download/index.htm
Изменить: Веб-сайт Чака Фалконера больше не доступен. archive.org все еще имеет копию , и я тоже размещаю копию .
Когда вы говорите «заранее», вы имеете в виду во время выполнения или во время компиляции? Во время компиляции вы делаете это:
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
Другого способа сделать это нет. Представьте себя с точки зрения программы: как можно узнать, сколько клавиш собирается нажать пользователь? Лучшее, что вы можете сделать, - это ограничить пользователя или любой другой ввод.
есть некоторые более сложные вещи, такие как создание связанного списка буферов и выделение фрагментов буферов с последующим их связыванием. Но я думаю, что это не тот ответ, который вы хотели здесь.
РЕДАКТИРОВАТЬ: В большинстве языков есть классы строк / буферов ввода, которые скрывают это от вас.
Вы должны выделить фиксированный буфер. Если он станет маленьким, то realloc ()
увеличьте его размер и продолжите.
В момент, когда вы читаете данные, ваш буфер будет иметь фиксированный размер - это неизбежно.
Что вы можете сделать, так это прочитать данные с помощью fgets и проверить, является ли последний символ '\ n' (или вы достигли конца файла), а если нет, realloc
ваш буфер и прочитайте больше.
Я редко нахожу это необходимым, но обычно выделяю один фиксированный буфер для чтения, считываю в него данные, а затем динамически выделяю место для его копии, выделяя только столько места, сколько она фактически занимает, а не все размер буфера, который я использовал изначально.
Невозможно определить длину строки, пока вы ее не прочитаете, поэтому чтение ее в буфер фиксированного размера - ваш единственный выбор.
Я полагаю, у вас есть альтернатива - читать строку небольшими порциями, но в зависимости от вашего приложения, которое может не предоставлять вам достаточно информации за раз для работы.
Возможно, самый простой способ справиться с этой дилеммой - определить максимальную длину для определенной входной строки ( #define
- помогает константа для этого значения). Используйте буфер этого заранее определенного размера всякий раз, когда вы читаете строку, но обязательно используйте форму строковых команд strncpy ()
, чтобы вы могли указать максимальное количество символов для чтения. Некоторые часто используемые типы строк (например, имена файлов или пути) могут иметь максимальную длину, определяемую системой.
Нет ничего «неправильного» в объявлении массива фиксированного размера, если вы его правильно используете (выполняйте правильную проверку границ и обрабатывайте случай, когда ввод будет переполнять массив). Это может привести к выделению неиспользуемой памяти, но, к сожалению, язык C не дает нам много работы, когда дело касается строк.
Существует концепция String Ropes , которая позволяет создавать деревья с буферами фиксированного размера. У вас все еще должны быть буферы фиксированного размера, от этого никуда не деться, но это довольно изящный способ динамического создания строк.