Выбрать главу

* Символы читаются из потока, пока одно из следующих условий не окажется истинным. Как только это случится, в очередную позицию массива помещается двоичный нуль. прочитано size-1 символов;

* встретился конец файла;

* встретился символ-ограничитель (еще раз напомним, что он остается в потоке и будет считан следующим).

Эта форма get() возвращает объект istream, для которого была вызвана (функция-член gcount() позволяет узнать количество прочитанных символов). Вот простой пример ее применения:

#include iostream

int main()

{

const int max_line = 1024;

char line[ max_line ];

while ( cin.get( line, max_line ))

{

// читается не больше max_line - 1 символов,

// чтобы оставить место для нуля

int get_count = cin.gcount();

cout "фактически прочитано символов: "

get_count endl;

// что-то сделать со строкой

// если встретился символ новой строки,

// удалить его, прежде чем приступать к чтению следующей

if ( get_count max_line-1 )

cin.ignore();

}

}

Если на вход этой программы подать текст о юной Алисе Эмме, то результат будет выглядеть так:

фактически прочитано символов: 52

фактически прочитано символов: 60

фактически прочитано символов: 66

фактически прочитано символов: 63

фактически прочитано символов: 61

фактически прочитано символов: 43

Чтобы еще раз протестировать поведение программы, мы создали строку, содержащую больше max_line символов, и поместили ее в начало текста. Получили:

фактически прочитано символов: 1023

фактически прочитано символов: 528

фактически прочитано символов: 52

фактически прочитано символов: 60

фактически прочитано символов: 66

фактически прочитано символов: 63

фактически прочитано символов: 61

фактически прочитано символов: 43

По умолчанию ignore() читает и удаляет один символ из потока, для которого вызвана, но можно и явно задать ограничитель и количество пропускаемых символов. В общем виде ее сигнатура такова:

ignore( streamsize length = 1, int delim = traits::eof )

ignore() читает и отбрасывает length символов из потока или все символы до ограничителя включительно или до конца файла и возвращает объект istream, для которого вызвана.

Мы рекомендуем пользоваться функцией getline(), а не get(), поскольку она автоматически удаляет ограничитель из потока. Сигнатура getline() такая же, как у get() с тремя аргументами (и возвращает она тоже объект istream, для которого вызвана):

getline(char *sink, streamsize size, char delimiter='\n')

Поскольку и getline(), и get() с тремя аргументами могут читать size символов или меньше, то часто нужно “спросить” у объекта istream, сколько символов было фактически прочитано. Это позволяет сделать функция-член gcount(): она возвращает число символов, прочитанных при последнем обращении к get() или getline().

Функция-член write() класса ostream дает альтернативный метод вывода массива символов. Вместо того чтобы выводить символы до завершающего нуля, она выводит указанное число символов, включая и внутренние нули, если таковые имеются. Вот ее сигнатура:

write( const char *sink, streamsize length )

Здесь length определяет, сколько символов выводить. write() возвращает объект класса ostream, для которого она вызвана.

Парной для функции write() из класса ostream является функция read() из класса istream с такой сигнатурой:

read( char* addr, streamsize size )

read() читает size соседних байт из входного потока и помещает их, начиная с адреса addr. Функция gcount() возвращает число байт, прочитанных при последнем обращении к read(). В свою очередь read() возвращает объект класса istream, для которого она вызвана. Вот пример использования getline(), gcount() и write():

#include iostream

int main()

{

const int lineSize = 1024;

int lcnt = 0; // сколько строк прочитано

int max = -1; // длина самой длинной строки

char inBuf[ lineSize ];

// читается до конца строки, но не более 1024 символов

while (cin.getline( inBuf, lineSize ))

{

// сколько символов фактически прочитано

int readin = cin.gcount();

// статистика: счетчик строк, самая длинная строка