Чтение онлайн

на главную - закладки

Жанры

Linux программирование в примерах

Роббинс Арнольд

Шрифт:

По достижении строки 83 программе нужно больше места в буфере. Именно здесь вступает в игру динамическое управление памятью. Обратите внимание на комментарий относительно сохранения значения

p
(строки 83-84); мы обсуждали это ранее в терминах повторной инициализации указателей для динамической памяти. Значение end также устанавливается повторно. Строка 89 изменяет размер памяти.

Обратите внимание, что здесь вызывается функция

xrealloc
. Многие программы GNU используют вместо
malloc
и
realloc
функции-оболочки, которые автоматически выводят сообщение об ошибке и завершают программу, когда стандартные процедуры возвращают
NULL
. Такая функция-оболочка может выглядеть таким образом:

extern const char *myname; /* установлено в main */

void *xrealloc(void *ptr, size_t amount) {

 void *p = realloc(ptr, amount);

 if (p == NULL) {

fprintf(stderr, "%s: out of memory!\n", myname);

exit(1);

 }

 return p;

}

Таким образом, если функция

xrealloc
возвращается, она гарантированно возвращает действительный указатель. (Эта стратегия соответствует принципу «проверки каждого вызова на ошибки», избегая в то же время беспорядка в коде, который происходит при таких проверках с непосредственным использованием стандартных процедур.) Вдобавок, это позволяет эффективно использовать конструкцию '
ptr = xrealloc(ptr, new_size)
', против которой мы предостерегали ранее.

Обратите внимание, что не всегда подходит использование такой оболочки. Если вы сами хотите обработать ошибки, не следует использовать оболочку. С другой стороны, если нехватка памяти всегда является фатальной ошибкой, такая оболочка вполне удобна.

97 if (ferror(ebuf->fp))

98 pfatal_with_name(ebuf->floc.filenm);

99

100 /* Если обнаружено несколько строк, возвратить их число.

101 Если не несколько, но _что-то_ нашли, значит, прочитана

102 последняя строка файла без завершающего символа конца

103 строки; вернуть 1. Если ничего не прочитано, это EOF;

104 возвратить -1. */

105 return nlines ? nlines : p == ebuf->bufstart ?
– 1 : 1;

106 }

В заключение, функция

readline
проверяет ошибки ввода/вывода, а затем возвращает описательное значение. Функция
pfatal_with_name
(строка 98) не возвращается. [44]

44

Эта функция завершает выполнение программы — Примеч. науч. ред.

3.2.1.9. Только GLIBC: чтение целых строк:

getline
и
getdelim

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

#define _GNU_SOURCE 1 /* GLIBC */

#include <stdio.h>

#include <sys/types.h> /* для ssize_t */

ssize_t getline(char **lineptr, size_t *n, FILE *stream);

ssize_t getdelim(char **lineptr, size_t *n, int delim, FILE *stream);

Определение константы

_GNU_SOURCE
вводит объявления функций
getline
и
getdelim
. В противном случае они неявно объявлены как возвращающие
int
. Для объявления возвращаемого типа
ssize_t
нужен файл
<sys/types.h>
. (
ssize_t
является «знаковым
size_t
». Он предназначен для такого же использования, что и
size_t
, но в местах, где может понадобиться использование также и отрицательных значений.)

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

getline
читает до символа конца строки, a
getdelim
использует в качестве разделителя символ, предоставленный пользователем. Общие аргументы следующие:

char **lineptr

Указатель на

char*
указатель для адреса динамически выделенного буфера. Чтобы
getline
сделала всю работу, он должен быть инициализирован
NULL
. В противном случае, он должен указывать на область памяти, выделенную с помощью
malloc
.

size_t *n

Указатель на размер буфера. Если вы выделяете свой собственный буфер,

*n
должно содержать размер буфера. Обе функции обновляют
*n
новым значением размера буфера, если они его изменяют.

FILE* stream

Место, откуда следует получать входные символы.

По достижении конца файла или при ошибке функция возвращает -1. Строки содержат завершающий символ конца строки или разделитель (если он есть), а также завершающий нулевой байт. Использование

getline
просто, как показано в
ch03-getline.с
:

/* ch03-getline.c --- демонстрация getline. */

#define _GNU_SOURCE 1

#include <stdio.h>

#include <sys/types.h>

/* main - прочесть строку и отобразить ее, пока не достигнут EOF */

int main(void) {

 char *line = NULL;

 size_t size = 0;

 ssize_t ret;

 while ((ret = getline(&line, &size, stdin)) != -1)

printf("(%lu) %s", size, line);

 return 0;

}

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

getline
увеличить размер буфера:

$ ch03-getline /* Запустить программу */

this is a line

(120) this is a line

And another line.

Поделиться:
Популярные книги

Кодекс Крови. Книга ХVII

Борзых М.
17. РОС: Кодекс Крови
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Кодекс Крови. Книга ХVII

Бастард Императора. Том 6

Орлов Андрей Юрьевич
6. Бастард Императора
Фантастика:
городское фэнтези
попаданцы
аниме
фэнтези
фантастика: прочее
5.00
рейтинг книги
Бастард Императора. Том 6

На границе империй. Том 9. Часть 2

INDIGO
15. Фортуна дама переменчивая
Фантастика:
космическая фантастика
попаданцы
5.00
рейтинг книги
На границе империй. Том 9. Часть 2

Серые сутки

Сай Ярослав
4. Медорфенов
Фантастика:
фэнтези
аниме
5.00
рейтинг книги
Серые сутки

Тонкий расчет

Шелдон Сидни
Детективы:
триллеры
8.86
рейтинг книги
Тонкий расчет

Хозяин Теней 6

Петров Максим Николаевич
6. Безбожник
Фантастика:
аниме
фэнтези
фантастика: прочее
попаданцы
5.00
рейтинг книги
Хозяин Теней 6

Осколки маски

Метельский Николай Александрович
7. Унесенный ветром
Фантастика:
боевая фантастика
альтернативная история
6.71
рейтинг книги
Осколки маски

Белые погоны

Лисина Александра
3. Гибрид
Фантастика:
фэнтези
попаданцы
технофэнтези
аниме
5.00
рейтинг книги
Белые погоны

Младший сын

Балашов Дмитрий Михайлович
1. Государи московские
Научно-образовательная:
история
8.50
рейтинг книги
Младший сын

Моров. Том 5

Кощеев Владимир
4. Моров
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Моров. Том 5

Древесный маг Орловского княжества 9

Павлов Игорь Васильевич
9. Орловское княжество
Фантастика:
аниме
фэнтези
попаданцы
5.00
рейтинг книги
Древесный маг Орловского княжества 9

Черный Маг Императора 7 (CИ)

Герда Александр
7. Черный маг императора
Фантастика:
фэнтези
попаданцы
5.00
рейтинг книги
Черный Маг Императора 7 (CИ)

Бояръ-Аниме. Газлайтер. Том 35

Володин Григорий Григорьевич
35. История Телепата
Фантастика:
аниме
боевая фантастика
фэнтези
5.00
рейтинг книги
Бояръ-Аниме. Газлайтер. Том 35

Вечный. Книга IV

Рокотов Алексей
4. Вечный
Фантастика:
боевая фантастика
попаданцы
рпг
5.00
рейтинг книги
Вечный. Книга IV