Стандартные потоки ввода-вывода

   
На этом шаге мы рассмотрим особенности использования стандартных потоков ввода-вывода.

   
У читателя может возникнуть законный вопрос: почему в программах предыдущих шагов использовались потоки ввода-вывода
cin, cout, cerr и ничего не требовалось знать о тех классах, к которым они относятся. Достаточно поместить в
текст программы препроцессорную процедуру:

      #include <iostream.h>

и можно с помощью операций включения (записи) данных в поток << и извлечения (чтения) данных из
потока >> выполнять обмен с дисплеем и клавиатурой ЭВМ.

   
Объясняется это тем, что заголовочный файл iostream.h не только подключает к программе описания классов
ios, istream, ostream, stream, но и содержит определения стандартных потоков ввода-вывода:

  • cin - объект класса istream, связанный со стандартным буферизированным входным потоком (обычно клавиатура консоли);
  • cout - объект класса ostream, связанный со стандартным буферизированным выходным потоком (обычно дисплей консоли);
  • cerr - объект класса ostream, связанный со стандартным небуферизированным выходным потоком (обычно дисплей консоли),
    в который направляются сообщения об ошибках;
  • clog - объект класса ostream, связанный со стандартным буферизированным выходным потоком
    (обычно дисплей консоли), в который с буферизацией направляются сообщения об ошибках.

   
Каждый раз при включении в программу файла iostream.h происходит формирование объектов
cin, cout, cerr, clog, т.е. создаются соответствующие стандартные потоки, и программисту становятся доступными связанные с ними
средства ввода-вывода. Программа может по своему усмотрению разорвать связь любого из перечисленных объектов с консолью и соединить его
с тем или иным файлом, но стандартная (по умолчанию) связь устанавливается именно с клавиатурой (поток cin) и дисплеем (потоки cout, cerr, clog).
В том же файле iostream.h, где описаны классы istream, ostream, для них определены оригинальные операции ввода и вывода данных.
Операция ввода класса istream называется извлечением (чтением) данных из потока. Она обозначается с помощью символа операции
сдвига вправо <<. Операция вывода класса ostream называется вставкой или включением (или записью) данных в поток.
Она обозначается с помощью символа операции сдвига влево >>. Роль операции извлечения и вставки конструкции << и >> играют
по умолчанию только в том случае, если слева от них находятся объекты, соответственно, классов iostream и ostream:

    cin >> имя_объекта_базового_типа 
    cout << выражение_базового_типа 
    cerr << выражение_базового_типа 
    clog << выражение_базового_типа

   
Выполнение операции >> (извлечение из потока) заключается в преобразовании последовательности символов потока
в значение типизированного объекта, частным случаем которого является переменная базового типа int, long, double и т.д.
При выполнении операции << (включение в поток) осуществляется обратное преобразование - типизированное значение выражения
(int, float, char и т.д.) трансформируется в последовательность символов потока. Примеры применении операций включения в поток и извлечения
из потока типизированных значений уже приводились многократно. Хорошо бы теперь читателю удивиться некоторым особенностям ввода-вывода с
помощью этих операций.

   
Дело в том, что внешнее (визуальное) представление данных никак не похоже на те внутренние коды, которые используются для их хранения
и обработки внутри ЭВМ. Вне ЭВМ это алфавитно-цифровые изображения (чисел или символов), внутри ЭВМ это двоичные коды - последовательности битов
(двоичных разрядов) регламентированной для каждого типа длины. При выполнении программы операция вывода данных (например, на экран дисплея)
предусматривает преобразование двоичных кодов в символы алфавита, изображаемые на внешнем устройстве. В операции ввода выполняется преобразование
сигналов от клавишей клавиатуры в двоичные коды внутреннего представления данных. Чтобы отвлечься (абстрагироваться) от особенностей аппаратурной
реализации устройств ввода-вывода, программист, работая на таком языке, как С++, использует входные и выходные потоки.
Поток в обоих случаях - это последовательность байтов (двоичных кодов фиксированной длины). При выводе коды потока могут
изображаться на экране в виде символов принятого алфавита. При вводе по кодам из потока формируются двоичные представления вводимых данных. Сложности
и вопросы появляются у программиста при преобразовании данных (кодов) из внешнего (потокового) во внутреннее представление и обратно.

   
Например, во внутреннем коде целое число может быть представлено двумя смежными байтами. Те же самые смежные байты можно рассматривать как внутренние
коды двух литер (символов). (Именно так действует объединение union в языке С++, позволяя по-разному интерпретировать внутренние коды
данных.)

   
Средства вывода, применяемые в языке, должны иметь возможность распознать тип выводимых данных и в указанном примере поместить в выходной поток
либо код внешнего представления целого числа, либо два кода расположенных рядом символов. Для обеспечения такой возможности операция << включения
в стандартный выходной поток перегружена. Существуют ее варианты для типов char, unsigned short, signed short, signed int, unsigned int, signed long, unsigned long, float double, long double, char *, void *.
Все они доступны после включения в программу файла iostream.h. Отметим, что операция включения определена только для указателей двух типов. Этого
вполне достаточно, так как все указатели, отличные от char *, автоматически приводятся к типу void *.

   
На следующем шаге мы более подробно остановимся на обмене данными со стандартными потоками.



Вы можете оставить комментарий, или Трекбэк с вашего сайта.

Оставить комментарий