При выделении памяти динамически, вы хотите изменить:
char line[2048];
в
#define MAXL 2048 /* the use of a define will become apparent when you */
size_t maxl = MAXL; /* need to check to determine if a realloc is needed */
char *line = malloc (maxl * sizeof *line);
if (!line) /* always check to insure allocation succeeded */
...error.. memory allocation failed
Вы читать дочитать до (maxl -1
) символов или newline
(при использовании fgetc
и т.д. ..) или прочитайте строку, а затем проверьте, line [strlen (line) - 1] == '\n'
, чтобы определить, читаете ли вы всю строку (если используете fgets
). (POSIX требует, чтобы все линии заканчивались newline
). Если вы читаете maxl
символов (fgetc
) или не читали новую строку (fgets
), то это короткое сообщение и больше символов осталось. Ваш выбор - realloc
(обычно удваивает размер) и повторите попытку. Для того, чтобы перераспределить:
char *tmp = realloc (line, 2 * maxl)
if (tmp) {
line = tmp;
maxl *= 2;
}
. Примечание: никогда перераспределить, используя исходный указатель (например line = realloc (line, 2 * maxl)
, потому что если realloc
терпит неудачу, память освобождается и указатель установлен на NULL
, и вы потеряете все данные, которые существовали в line
также обратите внимание, что maxl
обычно удваивается каждый раз при realloc
. Однако вы можете выбрать любую схему увеличения размера, которая вам нравится. (Если вас беспокоит обнуление всей выделенной выделенной памяти, вы можете использовать memset для инициализации вновь выделенного пространства до нуля/null. Полезно в некоторых ситуациях, когда вы хотите застраховать свой line
, всегда null-terminated
)
Это основная схема динамического распределения/перераспределения. Заметьте, что вы читаете, пока не прочитаете полную строку, поэтому вам нужно будет перестроить свой цикл теста. И, наконец, поскольку вы выделили память, вы несете ответственность за освобождение памяти, когда вы закончите с ней. Инструментом, с которым вы не можете жить, является valgrind
(или аналогичная программа проверки памяти), чтобы подтвердить, что вы не пропускаете память.
Совет, если вы читаете и хотите застраховать свою строку всегда null-terminated
, то после выделения своего блока памяти, ноль (0
) все символы. Как упоминалось ранее, есть memset
, но если вы выберете calloc
вместо malloc
, он будет нулевать для вас память. Однако в realloc
новое пространство НЕ равно нулю, так что вызов memset
требуется независимо от того, какая функция изначально назначила блок.
Tip2 Посмотрите на POSIX getline
. getline
будет обрабатывать распределение/перераспределение, если line
инициализирован до NULL
.getline
также возвращает количество фактически прочитанных символов, выдающих с необходимостью позвонить strlen
после fgets
, чтобы определить то же самое.
Дайте мне знать, если у вас есть дополнительные вопросы.
Вы всегда можете использовать 'getchar()' + 'realloc()', и есть также 'getline()'. –
http://stackoverflow.com/questions/2532425/read-line-from-file-without-knowing-the-line-length –
Мой ответ на аналогичный вопрос: http://stackoverflow.com/questions/28254245/ c-reading-a-text-file-separated-by-spaces-with-unbounded-word-size/28255082 # 28255082 –