Архитектура Аудит Военная наука Иностранные языки Медицина Металлургия Метрология Образование Политология Производство Психология Стандартизация Технологии |
Дополнительные операторы ввода/вывода
Иногда необходимо прочитать из входного потока последовательность не интерпретируемых байтов, а типов данных, таких, как char, int, string и т.д. Функция-член get() класса istream читает по одному байту, а функция getline() читает строку, завершающуюся либо символом перехода на новую строку, либо каким-то иным символом, определяемым пользователем. У функции-члена get() есть три формы: · get(char& ch) читает из входного потока один символ (в том числе и пустой) и помещает его в ch. Она возвращает объект iostream, для которого была вызвана. Например, следующая программа собирает статистику о входном потоке, а затем копирует входной поток в выходной:
} Функция-член put() класса ostream дает альтернативный метод вывода символа в выходной поток: put() принимает аргумент типа char и возвращает объект класса ostream, для которого была вызвана. После компиляции и запуска программа печатает следующий результат:
Alice Emma has long flowing red hair. Her Daddy says when the wind blows through her hair, it looks almost alive, like a fiery bird in flight. A beautiful fiery bird, he tells her, magical but untamed. " Daddy, shush, there is no such creature, " she tells him, at the same time wanting him to tell her more. Shyly, she asks, " I mean, Daddy, is there? "
наша статистика: пробелов: 59 символов новой строки: 6 табуляций: 0 точек: 4 запятых: 12
· вторая форма get() также читает из входного потока по одному символу, но возвращает не поток istream, а значение прочитанного символа. Тип возвращаемого значения равен int, а не char, поскольку необходимо возвращать еще и признак конца файла, который обычно равен -1, чтобы отличаться от кодов реальных символов. Для проверки на конец файла мы сравниваем полученное значение с константой EOF, определенной в заголовочном файле iostream. Переменная, в которой сохраняется значение, возвращенное get(), должна быть объявлена как int, чтобы в ней можно было представить не только код любого символа, но и EOF:
} При использовании любой из этих форм get() для чтения данной последовательности нужно семь итераций:
a b c d
Читаются следующие символы: ('a', пробел, 'b', пробел, 'c', символ новой строки, 'd'). На восьмой итерации читается EOF. Оператор ввода (> > ) по умолчанию пропускает пустые символы, поэтому на ту же последовательность потребуется четыре итерации, на которых возвращаются символы: 'a', 'b', 'c', 'd'. А вот следующая форма get() может прочесть всю последовательность всего за две итерации; · сигнатура третьей формы get() такова: get(char *sink, streamsize size, char delimiter='\n') sink – это массив, в который помещаются символы. size – это максимальное число символов, читаемых из потока istream. delimiter – это символ-ограничитель, при обнаружении которого чтение прекращается. Сам ограничитель не читается, а оставляется в потоке и будет прочитан следующим. Программисты часто забывают удалить его из потока перед вторым обращением к get(). Чтобы избежать этой ошибки, в показанной ниже программе мы воспользовались функцией-членом ignore() класса istream. По умолчанию ограничителем является символ новой строки. Символы читаются из потока, пока одно из следующих условий не окажется истинным. Как только это случится, в очередную позицию массива помещается двоичный нуль. · прочитано size-1 символов; · встретился конец файла; · встретился символ-ограничитель (еще раз напомним, что он остается в потоке и будет считан следующим). Эта форма get() возвращает объект istream, для которого была вызвана (функция-член gcount() позволяет узнать количество прочитанных символов). Вот простой пример ее применения:
} Если на вход этой программы подать текст о юной Алисе Эмме, то результат будет выглядеть так:
фактически прочитано символов: 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():
} Когда на вход было подано несколько фраз из романа Германа Мелвилла “Моби Дик”, программа напечатала следующее:
Строка #1 Прочитано символов: 45 Call me Ishmael. Some years ago, never mind
Строка #2 Прочитано символов: 46 how long precisely, having little or no money
Строка #3 Прочитано символов: 48 in my purse, and nothing particular to interest
Строка #4 Прочитано символов: 51 me on shore, I thought I would sail about a little
Строка #5 Прочитано символов: 47 and see the watery part of the world. It is a
Строка #6 Прочитано символов: 43 way I have of driving off the spleen, and
Строка #7 Прочитано символов: 28 regulating the circulation.
Всего прочитано строк: 7 Самая длинная строка: 51
Функция-член getline() класса istream поддерживает только ввод в массив символов. Однако в стандартной библиотеке есть обычная функция getline(), которая помещает символы в объект класса string: getline( istream & is, string str, char delimiter ); Эта функция читает не более str:: max_size()-1 символов. Если входная последовательность длиннее, то операция завершается неудачно и объект переводится в ошибочное состояние. В противном случае ввод прекращается, когда прочитан ограничитель (он удаляется из потока, но в строку не помещается) либо достигнут конец файла. Вот еще три необходимые нам функции-члена класса istream:
peek(); Следующий фрагмент иллюстрирует использование некоторых из них:
} Упражнение 20.4 Прочитайте из стандартного ввода следующую последовательность символов, включая все пустые, и скопируйте каждый символ на стандартный вывод (эхо-копирование):
a b c d e f
Упражнение 20.5 Прочитайте фразу “riverrun, from bend of bay to swerve of shore” сначала как последовательность из девяти строк, а затем как одну строку. Упражнение 20.6 С помощью функций getline() и gcount() прочитайте последовательность строк из стандартного ввода и найдите самую длинную (не забудьте, что строку, прочитанную за несколько обращений к getline(), нужно считать одной). |
Последнее изменение этой страницы: 2019-04-09; Просмотров: 317; Нарушение авторского права страницы