В языке программирования C++ библиотека ввода/вывода относится к семейству шаблонов классов и вспомогательных функций в стандартной библиотеке C++ , которые реализуют возможности потокового ввода/вывода. [1] [2] Это объектно-ориентированная альтернатива потокам C на основе FILE из стандартной библиотеки C. [3] [4]
Бьярне Страуструп , создатель C++, написал первую версию библиотеки потокового ввода-вывода в 1984 году как типобезопасную и расширяемую альтернативу библиотеке ввода-вывода C. [5] Библиотека претерпела ряд усовершенствований с момента этой ранней версии, включая введение манипуляторов для управления форматированием и шаблонизацию, позволяющую использовать ее с типами символов, отличными от char
.
Стандартизация 1998 года привела к перемещению библиотеки в std
пространство имен, а основной заголовок изменился с <iostream.h>
на <iostream>
. Именно эта стандартизированная версия рассматривается в остальной части статьи.
Большинство классов в библиотеке на самом деле являются очень обобщенными шаблонами классов. Каждый шаблон может работать с различными типами символов, и даже сами операции, такие как сравнение двух символов на предмет равенства, могут быть настроены. Однако большая часть кода должна выполнять операции ввода и вывода, используя только один или два типа символов, поэтому большую часть времени доступ к функциональности осуществляется через несколько typedef , которые указывают имена для часто используемых комбинаций шаблона и типа символа.
Например, basic_fstream<CharT,Traits>
относится к шаблону универсального класса, который реализует операции ввода/вывода в файловых потоках. Обычно он используется как , fstream
что является псевдонимом для basic_fstream<char,char_traits<char>>
, или, другими словами, basic_fstream
работая с символами типа char
с набором операций по умолчанию.
Классы в библиотеке можно условно разделить на две категории: абстракции и реализации. Классы, попадающие в категорию абстракций, предоставляют интерфейс, достаточный для работы с любым типом потока. Код, использующий такие классы, не зависит от точного места, откуда считываются или куда записываются данные. Например, такой код может записывать данные в файл, буфер памяти или веб-сокет без перекомпиляции. Классы реализации наследуют классы абстракции и предоставляют реализацию для конкретного типа источника или приемника данных. Библиотека предоставляет реализации только для потоков на основе файлов и потоков на основе буфера памяти.
Классы в библиотеке также можно разделить на две группы по тому, реализуют ли они операции низкого или высокого уровня. Классы, которые имеют дело с низкоуровневыми вещами, называются потоковыми буферами. Они работают с символами, не предоставляя никакой функциональности форматирования. Эти классы очень редко используются напрямую. Классы высокого уровня называются потоками и предоставляют различные возможности форматирования. Они построены поверх потоковых буферов.
В следующей таблице перечислены и классифицированы все классы, предоставляемые библиотекой ввода-вывода.
Классы библиотеки ввода/вывода находятся в нескольких заголовках.
<ios>
содержит определения ios_base
и basic_ios
классы, которые управляют информацией о форматировании и связанным с ней потоковым буфером.<istream>
содержит определение basic_istream
шаблона класса, реализующего форматированный ввод.<ostream>
содержит определение basic_ostream
шаблона класса, реализующего форматированный вывод.<iostream>
содержит определение basic_iostream
шаблона класса, который реализует форматированный ввод и вывод, и включает в себя <ios>
, <istream>
и <ostream>
.<fstream>
содержит определения basic_ifstream
и шаблоны классов, которые реализуют форматированный ввод, вывод и ввод basic_ofstream
/ basic_fstream
вывод в файловых потоках.<sstream>
содержит определения basic_istringstream
и шаблоны классов, которые реализуют форматированный ввод, вывод и ввод basic_ostringstream
/ basic_stringstream
вывод в строковых потоках.<iomanip>
содержит манипуляторы форматирования.<iosfwd>
содержит предварительные объявления всех классов в библиотеке ввода/вывода.В языке C++ в виде таблицы определены двенадцать классов потоковых буферов.
ios_base
и basic_ios
два класса, которые управляют битами нижнего уровня потока. ios_base
хранят информацию о форматировании и состоянии потока. basic_ios
управляют связанным буфером потока. basic_ios
обычно известны как просто ios
или wios
, которые являются двумя typedef для basic_ios
определенного типа символа. basic_ios
и ios_base
очень редко используются программистами напрямую. Обычно их функциональность доступна через другие классы, такие как , iostream
которые их наследуют. [6] [7]
Потоки ввода/вывода C++ в первую очередь определяются iostream
, заголовочным файлом , который является частью стандартной библиотеки C++ (название расшифровывается как Input / Output Stream ). В C++ и его предшественнике, языке программирования C , нет специального синтаксиса для потокового ввода или вывода данных. Вместо этого они объединены в библиотеку функций . Как и заголовок, унаследованный от stdio.h языка C , предоставляет базовые службы ввода и вывода для программ на C++. iostream использует объекты , , , и для отправки данных в и из стандартных потоков ввода, вывода, ошибки (небуферизованные) и журнала (буферизованные) соответственно. Как часть стандартной библиотеки C++ , эти объекты являются частью пространства имен . [8]cstdio
iostream
cin
cout
cerr
clog
std
Объект cout
имеет тип ostream
, который перегружает левый оператор побитового сдвига , чтобы заставить его выполнить операцию, совершенно не связанную с побитовыми операциями , и, в частности, вычислить значение левого аргумента, что позволяет выполнять несколько операций над одним и тем же объектом ostream, по сути, как другой синтаксис для каскадирования методов , предоставляя текучий интерфейс . Объекты и также имеют тип , поэтому они перегружают и этот оператор. Объект имеет тип , который перегружает правый оператор побитового сдвига. Направления операторов побитового сдвига создают впечатление, что данные текут к выходному потоку или утекают от входного потока.cerr
clog
ostream
cin
istream
Манипуляторы — это объекты, которые могут изменять поток с помощью операторов <<
или >>
.
Другие манипуляторы можно найти, воспользовавшись заголовком iomanip
.
Манипуляторы форматирования должны быть «сброшены» в конце, иначе программист неожиданно получит их эффект в следующем выходном операторе.
Некоторые реализации стандартной библиотеки C++ имеют значительное количество мертвого кода . Например, GNU libstdc++ автоматически создает локаль при построении, дажеostream
если программа никогда не использует какие-либо типы (дата, время или деньги), на которые влияет локаль, [9]
а статически связанная программа "Hello, World!" , использующая <iostream>
GNU libstdc++, создает исполняемый файл на порядок больше, чем эквивалентная программа, использующая <cstdio>
. [10] Существуют частичные реализации стандартной библиотеки C++, разработанные для сред с ограниченным пространством; они <iostream>
могут не включать функции, которые программам в таких средах могут не понадобиться, например, поддержку локали. [11]
Каноническую программу «Hello, World!» можно выразить следующим образом:
#include <iostream> int main () { std :: cout << "Привет, мир!" << std :: endl ; }
Эта программа выведет «Hello, world!», за которым последует новая строка и очистка буфера стандартного потока вывода.
В следующем примере создается файл с именем «file.txt» и в него помещается текст «Hello, world!» с последующим символом новой строки.
#include <fstream> int main () { std :: ofstream file ( "file.txt" ); file << "Привет, мир!" << std :: endl ; }
...endl, который очищает выходной буфер и отправляет новую строку в стандартный поток вывода.
bits/ios_base.h