Поток — это абстрактное понятие, относящееся к любому переносу данных от источника к приемнику. Потоки C++, в отличие от функций ввода/вывода в стандартном С, обеспечивают надежную работу как со стандартными, так и с определенными пользователем типами данных, а также единообразный и понятный синтаксис.
Чтение данных из потока называется извлечением, вывод в поток — помещением, или включением. Поток определяется как последовательность байтов и не зависит от конкретного устройства, с которым производится обмен (оперативная память, файл на диске, клавиатура или принтер). Обмен с потоком для увеличения скорости передачи данных производится, как правило, через специальную область оперативной памяти — буфер. Фактическая передача данных выполняется при выводе после заполнения буфера, а при вводе — если буфер исчерпан.
По направлению обмена потоки можно разделить на входные (данные вводятся в память), выходные (данные выводятся из памяти) и двунаправленные (допускающие как извлечение, так и включение).
По виду устройств, с которыми работает поток, можно разделить потоки на стандартные, файловые и строковые.
Стандартные потоки предназначены для передачи данных от клавиатуры и на экран дисплея, файловые потоки — для обмена информацией с файлами на внешних носителях данных (например, на магнитном диске), а строковые потоки — для работы с массивами символов в оперативной памяти.
Для поддержки потоков библиотека C++ содержит иерархию классов, построенную на основе двух базовых классов — iosи streambuf. Класс ios содержит общие для ввода и вывода поля и методы, класс streambuf обеспечивает буферизацию потоков и их взаимодействие с физическими устройствами.
Основным преимуществом потоков по сравнению с функциями ввода/вывода, унаследованными из библиотеки С, является контроль типов, а также расширяемость, то есть возможность работать с типами, определенными пользователем. Для этого требуется переопределить операции потоков.
К недостаткам потоков можно отнести снижение быстродействия программы, которое в зависимости от реализации компилятора может быть весьма значительным.
Заголовочный файл <iostream> содержит, кроме описания классов для ввода/вывода, четыре предопределенных объекта потокового ввода/вывода.
Эти объекты создаются при включении в программу заголовочного файла <iostream>, при этом становятся доступными связанные с ними средства ввода/вывода. Имена этих объектов можно переназначить на другие файлы или символьные буферы.
Манипуляторами называются функции, которые можно включать в цепочку операций помещения и извлечения для форматирования данных. Манипуляторы делятся на простые, не требующие указания аргументов, и параметризованные. Пользоваться манипуляторами более удобно, чем методами установки флагов форматирования.
Таблица 5 — Манипуляторы
Манипулятор
Назначение
Ввод\вывод
dec
Вывод чисел в десятичной системе счисления
Вывод
endl
Вывод символа новой строки и флэширование
Вывод
ends
Вывод нуля (NULL)
Ввод\вывод
flush
Флэширование
Вывод
hex
Вывод чисел в шестнадцатеричной системе счисления
Вывод
oct
Вывод чисел в восьмеричной системе счисления
Вывод
resetiosflags(long f)
Сбросить флаги, определяемые f
Ввод\вывод
setbase(int base)
Установить основание системы счисления
Вывод
1
setfill(char ch)
Установить символ заполнения ch
Вывод
setiosflags(long f)
Установить флаги, задаваемые f
Ввод\вывод
setprecision(int p)
Установить точность, равную р
Вывод
setw(int w)
Установить ширину поля, равную w
Вывод
ws
Пропуск начальных пробелов
Ввод
Пример c манипуляторами setw, setfill и setprecision: