Файлы. Общая концепция организации ввода-вывода данных в С++. Средства класса ios, обеспечивающие точную настройку вывода, страница 5

cin – объект класса istream, соответствующий стандартному потоку ввода (stdin в С), по умолчанию связан с клавиатурой;

cout – объект класса ostream, соответствующий стандартному потоку вывода (stdout в С), по умолчанию связан с экраном;

clog – объект класса ostream, соответствующий стандартному буферизованному потоку вывода для ошибок, по умолчанию связан с экраном;

cerr – объект класса ostream, соответствующий стандартному небуферизованному потоку вывода для ошибок, по умолчанию связан с экраном.

Форматированный ввод/вывод реализуется через перегруженные операции:

§  операция сдвига влево ‘<<’ перегружена для вывода в поток и называется операцией вставки (помещения, включения) в поток;

§  операция сдвига вправо ‘>>’ перегружена для вводи из потока и называется операцией извлечения из потока.

Например, в классе ostream определены операции:

ostream& operator<<(short);

ostream& operator<<(int);

ostream& operator<<(double); и т.д.

Если в программе встретятся операторы:

int x=5;

cout << x;

компилятор сначала определит, что левый аргумент имеет тип ostream, а правый – тип int; найдет прототип метода ostream& operator<<(int) в заголовочном файле и вызовет метод cout.operator<<(x); в результате работы которого мы увидим на экране число 5. При этом (по умолчанию) обеспечивается преобразование значения встроенных типов в строку символов.

Аналогично происходит работа со стандартным потоком ввода через объект cin.

Если форматирование по умолчанию вас не устраивает, можно воспользоваться дополнительными средствами: либо соответствующими методами (функциями-членами) класса ios, либо так называемыми манипуляторами ввода/вывода. Последние представляют собой функции, которые можно включать прямо в поток. Они определены частично в файлах istream и ostream, частично в файле iomanip.

Например, вывести значение целой переменной х в шестнадцатеричном формате можно двумя способами:

cout.flags(ios::hex);

cout << x;

или

cout << hex<< x;

Очевидно, что код с использованием манипулятора в данном случае более лаконичен и выразителен.

Стандартные потоки ввода и вывода буферизованы. Наличие буфера в стандартном входном потоке создает некоторые особенности; в процессе набора данных на клавиатуре они отображаются на экране, но не извлекаются из потока – это дает возможность исправлять ошибки; «чтение» происходит оттуда.

При этом при вводе:

o  вся строка помещается в буфер ввода;

o  ввод завершается нажатием <enter>; извлечение из буфера – только после нажатия <enter>;

при чтении игнорируются начальные пробельные символы; чтение начинается с первого непробельного символа;

ограничителем значения числа является нечисловой или пробельный символ; ограничителем строки – пробельный символ;

o  оператор чтения осуществляет разбор и преобразование последовательности вводимых символов в двоичное представление в соответствии с типом приемника; ввод в переменную прекращается при наборе недопустимого для данного типа символа (int ii; double dd; cin>>ii; cin >>dd; при наборе числа 123.456 ii получит значение 123, dd получит значение 0.456;

при вводе целых чисел читаются: +, -, десятичная цифра; числа должны во входном потоке разделяться обобщенными пробельными символами (пробелы, знаки табуляции, символы перевода строки - <enter>);

при вводе 16-ичных целых чисел дополнительно читаются также буквы a, A, b, B, ….f, F;

при вводе вещественных чисел – дополнительно читаются символы e или E и «точка»;

булевские значения вводятся как 1 (true) и 0 (false); при вводе-выводе булевских значений помогает флаг boolalpha (ввод-вывод true и false вместо 1 и 0);

ввод перечислимого типа как целого по умолчанию не работает; для каждого нового перечислимого типа необходимо писать собственные операции ввода-вывода;