На этом шаге мы рассмотрим особенности использования функций ввода.
В следующих определениях istream обозначает потоковый класс, используемый для чтения. Это может быть класс istream, wistream или любая другая специализация класса шаблона basic_istream. Параметр char обозначает соответствующий тип символов (char для istream, wchar_t для wistream). Другие типы и значения, выводимые курсивом, зависят от определения типа символов или класса трактовок, связанного с потоком данных.
В стандартную библиотеку C++ входят несколько функций потоковых классов для чтения последовательностей символов. Возможности этих функций сравниваются в таблице 1.
Функция | Признак конца чтения | Количество символов | Присоединение завершителя | Возвращаемый тип |
---|---|---|---|---|
get(s, num) | Новая строка (без включения) или конец файла | До num-1 | Да | istream |
get(s, num, t) | t (без включения) или конец файла | До num-1 | Да | istream |
getline(s, num) | Новая строка (с включением) или конец файла | До num-1 | Да | istream |
getline(s, num, t) | t (с включением) или конец файла | До num-1 | Да | istream |
read(s, num) | Конец файла | num | Нет | istream |
readsome(s, num) | Конец файла | До num | Нет | streamsize |
int istream::get ()
В общем случае возвращаемое значение относится к типу traits::int_type, a EOF - величина, возвращаемая при вызове traits::eof(). Для istream это соответственно тип int и константа EOF. Следовательно, для istream эта функция соответствует функциям getchar() и getc() языка С.
Возвращаемое значение не обязательно относится к типу символов потока данных; оно также может относиться к типу с более широким диапазоном значений. Без этого было бы невозможно отличить EOF от символа с соответствующим значением.
istream& istream::get (char& с)
istream& istream::get (char* str, streamsize count)
istream& istream::get (char* str, streamsize count, char delim)
Первая форма завершает чтение, если следующий читаемый символ является символом новой строки соответствующей кодировки. Для istream это символ \n, а для wistream - символ wchar_t('\n'). В общем случае используется символ widen('\n').
Вторая форма завершает чтение, если следующий читаемый символ является разделителем delim.
Обе формы возвращают объект потока данных, по состоянию которого можно проверить, успешно ли выполнено чтение.
Завершающий символ (delim) не читается.
Символ завершения строки прерывает чтение.
Перед вызовом необходимо убедиться в том, что размер str достаточен для хранения count символов.
istream& istream::getline (char* str, streamsize count)
istream& istream::getline (char* str, streamsize count, char delim)
istream& istream::read (char* str, streamsize count)
Строка str не завершается автоматически символом завершения строки.
Перед вызовом необходимо убедиться в том, что размер str достаточен для хранения count символов.
Обнаружение признака конца файла в процессе чтения считается ошибкой, для которой устанавливается бит failbit (вдобавок к флагу eofbit).
streamsize istream::readsome (char* str, streamsize count)
Строка str не завершается автоматически символом завершения строки.
Перед вызовом необходимо убедиться в том, что размер str достаточен для хранения count символов.
В отличие от функции read() функция readsome() читает из потокового буфера все доступные символы (при помощи функции in_avail() класса буфера). Например, она может использоваться в ситуациях, когда ввод поступает с клавиатуры или от других процессов, поэтому ожидание нежелательно. Обнаружение конца файла не считается ошибкой, а биты eofbit и failbit не устанавливаются.
streamsize istream::gcount () const
istream& istream::ignore ()
istream& istream::ignore (streamsize count)
istream& istream::ignore (streamsize count, int delim)
Первая форма игнорирует один символ. Вторая форма игнорирует до count символов. Третья форма игнорирует до count символов и прекращает работу тогда, когда будет извлечен и проигнорирован символ delim.
Если значение count равно std::numeric_limits<std::streamsize>::max(), то есть максимальному значению типа std::streamsize, функция игнорирует все символы до тех пор, пока не будет обнаружен ограничитель delim или конец файла.
Все формы возвращают объект потока данных.
Примеры:
cin.ignore(numeric_limits<std::streamsize>::max(),'\n');
cin.ignore(numeric_limits<std::streamsize>::max());
int istream::peek ()
Если дальнейшее чтение невозможно, возвращает EOF. EOF - значение, возвращаемое traits::eof(). Для класса istream это константа EOF.
istream& istream::unget ()
istream& istream::putback (char c)
Различия между функциями unget и pushback() заключаются в том, что putback() проверяет, был ли передаваемый символ с последним считанным символом.
Если символ не удается вернуть или функция putback() пытается вернуть другой символ, устанавливается флаг badbit, что может привести к выдаче соответствующего исключения.
Максимальное количество символов, которые могут быть возвращены в поток данных этими функциями, зависит от реализации. По стандарту гарантированно работает только один вызов этих функций между двумя операциями чтения. Следовательно, только этот вариант может считаться переносимым.
При чтении С-строк описанные здесь функции безопаснее оператора >>, поскольку они требуют явной передачи максимального размера читаемой строки. Хотя количество читаемых символов можно ограничить и при использовании оператора >>, об этом часто забывают.
Вместо использования потоковых функций ввода часто удобнее работать с потоковым буфером напрямую. Функции потоковых буферов позволяют эффективно читать отдельные символы или последовательности символов без затрат на конструирование объектов sentry. Также можно воспользоваться шаблонным классом istreambuf_iterator, предоставляющим итераторный интерфейс к потоковому буферу.
Функции tellg() и seekg() предназначены для изменения текущей позиции чтения. В основном они используются при работе с файлами.
На следующем шаге мы рассмотрим функции вывода.