23.1 – Потоки ввода и вывода (I/O)
Функциональные возможности ввода и вывода не определены как часть ядра языка C++, а предоставляются через стандартную библиотеку C++ (и, таким образом, находятся в пространстве имен std
). В предыдущих уроках вы включали заголовок библиотеки iostream
и использовали объекты cin
и cout
для выполнения простого ввода/вывода. В этом уроке мы рассмотрим библиотеку iostream
более подробно.
Библиотека iostream
Когда вы включаете заголовок iostream
, вы получаете доступ ко всей иерархии классов, отвечающих за обеспечение функциональности ввода/вывода (включая класс, который на самом деле называется iostream
). Иерархия классов, не относящихся к файловому вводу/выводу, выглядит следующим образом:
Первое, что вы можете заметить в этой иерархии, – это то, что она использует множественное наследование (этого мы просили избегать, если это вообще возможно). Однако библиотека iostream
была разработана и тщательно протестирована, чтобы избежать каких-либо типовых проблем множественного наследования, поэтому вы можете использовать ее свободно, без опасений.
Потоки
Во-вторых, вы можете заметить, что слово «поток» используется очень часто. По сути, ввод/вывод в C++ реализуется с помощью потоков. Абстрактно, поток – это просто последовательность байтов, к которой можно получить доступ последовательно. Со временем поток может выдавать или принимать потенциально неограниченные объемы данных.
Обычно мы имеем дело с двумя разными типами потоков. Входные потоки используются для хранения входных данных от источника данных, такого как клавиатура, файл или сеть. Например, пользователь может нажать клавишу на клавиатуре, в то время как программа в данный момент не ожидает входных данных. Вместо того чтобы игнорировать нажатия клавиш пользователем, данные помещаются во входной поток, где они будут ждать, пока программа не будет к ним готова.
И наоборот, выходные потоки используются для хранения выходных данных для конкретного потребителя данных, такого как монитор, файл или принтер. При записи данных на устройство вывода это устройство может быть еще не готово принять эти данные – например, принтер всё еще может прогреваться, когда программа записывает данные в свой выходной поток. Данные будут находиться в этом выходном потоке, пока принтер не начнет их использовать.
Некоторые устройства, такие как файлы и сети, могут быть источниками как входных, так и выходных данных.
Самое приятное в потоках – это то, что, чтобы читать и записывать данные на множество различных типов устройств, программисту только нужно научиться взаимодействовать с потоками. Подробности о том, как потоки взаимодействуют с реальными устройствами, к которым они подключены, оставлены на усмотрение среды или операционной системы.
Ввод/вывод в C ++
Хотя класс ios
обычно является производным от ios_base
, ios
обычно будет самым базовым классом, с которым вы будете работать напрямую. Класс ios
определяет множество вещей, общих как для входных, так и для выходных потоков. Мы разберемся с этим в следующем уроке.
Класс istream
– это основной класс, используемый при работе с входными потоками. Для входных потоков оператор извлечения (>>
) используется для удаления значений из потока. Это должно быть понятно: когда пользователь нажимает клавишу на клавиатуре, код клавиши помещается во входной поток. Затем ваша программа извлекает это значение из потока, чтобы его можно было использовать.
Класс ostream
– это основной класс, используемый при работе с выходными потоками. В выходных потоках оператор вставки (<<
) используется для помещения значений в поток. Это также должно быть понятно: вы вставляете свои значения в поток, а потребитель данных (например, монитор) использует их.
Класс iostream
может обрабатывать как ввод, так и вывод, обеспечивая двунаправленный ввод/вывод.
Наконец, есть несколько классов, заканчивающихся на "_withassign". Эти классы потоков являются производными от istream
, ostream
и iostream
(соответственно) с определенным оператором присваивания, позволяющим присваивать один поток другому. В большинстве случаев вы не будете иметь дело с этими классами напрямую.
Стандартные потоки в C++
Стандартный поток – это предварительно подключенный поток, предоставляемый компьютерной программе ее средой. C++ поставляется с четырьмя предопределенными объектами стандартных потоков, которые уже настроены для использования. Первые три вы видели раньше:
cin
– классistream_withassign
, привязанный к стандартному вводу (обычно к клавиатуре);cout
– классostream_withassign
, связанный со стандартным выводом (обычно монитором);cerr
– классostream_withassign
, связанный со стандартным выводом сообщений об ошибках (обычно монитор), обеспечивающий небуферизованный вывод;clog
– классostream_withassign
, связанный со стандартным выводом сообщений об ошибках (обычно монитор), обеспечивающий буферизованный вывод.
Небуферизованный вывод обычно обрабатывается немедленно, тогда как буферизованный вывод обычно сохраняется и выдается блоками. Поскольку clog
используется не очень часто, его часто не включают в список стандартных потоков.
В следующем уроке мы более подробно рассмотрим некоторые функциональные возможности, связанные с вводом/выводом.