* Символы читаются из потока, пока одно из следующих условий не окажется истинным. Как только это случится, в очередную позицию массива помещается двоичный нуль. прочитано 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();
// статистика: счетчик строк, самая длинная строка
++lcnt;
if ( readin max )
max = readin;