Функции
Это глобальные функции шаблона, определенные в . Сведения о функциях-членах см. в документации по классу basic_ostream .
endl
Завершает строку и очищает буфер.
template class basic_ostream& endl( basic_ostream& Ostr);
Параметры
Ostr
Объект типа basic_ostream.
Возвращаемое значение
Объект типа basic_ostream.
Замечания
Манипулятор вызывает Ostr.put(Ostr.widen(‘\n’)), а затем вызывает Ostr.смыть. Он возвращает Ostr.
Пример
// ostream_endl.cpp // compile with: /EHsc #include int main( )
testing
концы
template class basic_ostream& ends( basic_ostream& Ostr);
Параметры
Ostr
Объект типа basic_ostream .
Возвращаемое значение
Объект типа basic_ostream .
Замечания
Манипулятор вызывает Ostr.put(Elem(‘\0’)). Он возвращает Ostr.
Пример
// ostream_ends.cpp // compile with: /EHsc #include int main( )
ab c
flush
template class basic_ostream& flush( basic_ostream& Ostr);
Параметры
Ostr
Объект типа basic_ostream .
Возвращаемое значение
Объект типа basic_ostream .
Замечания
Манипулятор вызывает Ostr.смыть. Он возвращает Ostr.
Пример
// ostream_flush.cpp // compile with: /EHsc #include int main( )
testing
swap
Меняет местами значения двух объектов basic_ostream .
template void swap( basic_ostream& left, basic_ostream& right);
Параметры
left
Ссылка lvalue на объект basic_ostream .
right
Ссылка lvalue на объект basic_ostream .
Замечания
Функция шаблона swap выполняет left.swap(right) .
Ostream c что это
Обратная связь
Определяет шаблон класса basic_ostream, который медиатирует вставки для iostreams. Заголовок также определяет несколько связанных манипуляторов. (Обычно этот заголовок включается другими заголовками iostreams. Вам редко нужно включить его напрямую.)
Синтаксис
#include
Определения типов
| Введите имя | Description |
|---|---|
| ostream | Создает тип из basic_ostream , который специализируется на char , и char_traits , который специализируется на char . |
| wostream | Создает тип из basic_ostream , который специализируется на wchar_t , и char_traits , который специализируется на wchar_t . |
Манипуляторы
| Имя | Описание |
|---|---|
| endl | Завершает строку и очищает буфер. |
| ends | Завершает строку. |
| flush | Очищает буфер. |
| swap | Меняет местами значения левого параметра объекта basic_ostream со значениями правого параметра объекта basic_ostream . |
Операторы
| Operator | Description |
|---|---|
| operator | Записывает в поток различные типы. |
Классы
| Класс | Description |
|---|---|
| basic_ostream | Шаблон класса описывает объект, который управляет вставкой элементов и закодированными объектами в буфер потока. |
Потоки и система ввода-вывода
Все инструменты для работы с системой ввода-вывода и потоками в языке С++ определены в стандартной библиотеке. Заголовочный файл iostream определяет следующие базовые типы для работы с потоками:
- istream и wistream : читают данные с потока
- ostream и wostream : записывают данные в поток
- iostream и wiostream : читают и записывают данные в поток
Для каждого типа определен его двойник, который начинается на букву w и который предназначен для поддержки данных типа wchar_t.
Эти типы являются базовыми для других классов, управляющих потоками ввода-вывода.
Объект типа ostream получает значения различных типов, преобразует их в последовательность символов и передает их через буфер в определенное место для вывода (консоль, файл, сетевые интерфейсы и т.д.)

Поток istream получает через буфер из определенного места последовательности символов (с консоли, из файла, из сети и т.д.) и преобразует эти последовательности в значения различных типов. То есть когда мы вводим данные (с той же клавиатуры в консоли), сначала данные накапливаются в буфере и только затем передаются объекту istream.

По умолчанию в стандартной библиотеке определены объекты этих классов — cout , cin , cerr , которые работают с консолью.
Запись в поток
К примеру, по умолчанию стандартная библиотека C++ предоставляет объект cout , который представляет тип ostream и позволяет выводить данные на консоль:
#include int main()
std::coutЧтение данных
Для чтения данных из потока применяется оператор ввода >> , который принимает два операнда. Левый операнд представляет поток istream, с которого производится считывание, а правый операнд - объект, в который считываются данные.
Для чтения с консоли применяется объект cin , который представляет тип istream.
#include int main() < int age; double weight; std::cout > age; std::cout > weight; std::coutОднако такой способ не очень подходит для чтения строк с консоли особенно когда считываемая строка содержит пробельные символы. В этом случае лучше использовать встроенную функцию getline() , которая в качестве параметра принимает поток istream и переменную типа string, в которую надо считать данные:
#include int main() < std::string name; std::cout > name; std::coutПример работы программы:
Input name: Tom Smit Your name: Tom SmitПо умолчанию признаком окончания ввода служит перевод на другую строку, например, с помощью клавиши Enter. Но также можно задать свой признак окончания ввода с помощью дополнительного параметра функции getline() . Для этого надо передать символ, который будет служить окончанием ввода:
#include int main() < std::string text; std::cout << "Input text: " << std::endl; getline(std::cin, text, '*'); // окончанием ввода будет служить символ * std::cout
В данном случае ввод завершится, когда пользователь введет символ *. Таким образом, мы можем ввести многострочный текст, но при вводе звездочки ввод завершится. Пример работы программы:
Input text: Hello World Good bye world* Your text: Hello World Good bye worldВывод ошибок
Для вывода сообщения об ошибке на консоль применяется объект cerr , который представляет объект типа ostream:
#include int main()
Потоки символов wchar_t
Для работы с потоками данных типов wchar_t в стандартной библиотеке определены объекты wcout (тип wostream), wcerr (тип wostream) и wcin (тип wistream), которые являются аналогами для объектов cout, cerr и cin и работают аналогично
#include int main() < int age; double weight; std::wcout > age; std::wcout > weight; if (age
23.3 – Вывод данных с помощью ostream и ios
В этом разделе мы рассмотрим различные аспекты класса библиотеки iostream для вывода данных ( ostream ).
Примечание. Все функции ввода/вывода в этом уроке находятся в пространстве имен std . Это означает, что все объекты и функции ввода/вывода должны иметь префикс std:: , или должна быть использована инструкция using namespace std; .
Оператор вставки
Оператор вставки используется для записи данных в выходной поток. В C++ уже есть предопределенные операции вставки для всех встроенных типов данных, а как перегрузить оператор вставки для пользовательских классов, мы рассмотрели в уроке «13.4 – Перегрузка операторов ввода/вывода».
В уроке о потоках вы видели, что и istream , и ostream были производными от класса с именем ios . Одна из задач ios (и ios_base ) – управлять параметрами форматирования вывода.
Форматирование
Есть два способа изменить параметры форматирования: флаги и манипуляторы. Вы можете думать о флагах как о логических переменных, которые можно включать и выключать. Манипуляторы – это объекты, помещенные в поток, которые влияют на способ ввода и вывода.
Чтобы включить флаг, используйте функцию setf() с соответствующим флагом в качестве параметра. Например, по умолчанию C++ не выводит знак + перед положительными числами. Однако, используя флаг std::ios::showpos , мы можем изменить это поведение:
std::cout.setf(std::ios::showpos); // включить флаг std::ios::showpos std::coutЭто приводит к следующему выводу:
Можно включить сразу несколько флагов ios с помощью оператора ИЛИ ( | ):
// включить флаги std::ios::showpos и std::ios::uppercase std::cout.setf(std::ios::showpos | std::ios::uppercase); std::coutЧтобы отключить флаг, используйте функцию unsetf() :
std::cout.setf(std::ios::showpos); // включить флаг std::ios::showpos std::coutЭто приводит к следующему выводу:
+27 28Есть еще одна хитрость при использовании setf() , о которой следует упомянуть. Многие флаги принадлежат группам, называемым группами форматирования. Группа форматирования – это группа флагов, которые управляют аналогичными (иногда взаимоисключающими) параметрами форматирования. Например, группа форматирования с именем basefield содержит флаги oct , dec и hex , которые управляют основанием целочисленных значений. По умолчанию установлен флаг dec . Следовательно, если мы сделаем это:
std::cout.setf(std::ios::hex); // попытаться включить шестнадцатеричный вывод std::coutТо получим такой вывод:
Не сработало! Причина в том, что setf() только включает флаги – этого недостаточно, чтобы отключить взаимоисключающие флаги. Следовательно, когда мы включили std::hex , std::ios::dec всё еще был включен, а std::ios::dec явно имеет приоритет. Есть два способа обойти эту проблему.
Во-первых, мы можем отключить std::ios::dec , чтобы был установлен только std::hex :
std::cout.unsetf(std::ios::dec); // выключаем десятичный вывод std::cout.setf(std::ios::hex); // включаем шестнадцатеричный вывод std::coutТеперь мы получаем ожидаемый результат:
Второй способ – использовать другую форму setf() , которая принимает два параметра: первый параметр – это флаг, который нужно установить, а второй – это группа форматирования, к которой он принадлежит. При использовании этой формы setf() все флаги, принадлежащие группе, отключаются, и включается только переданный флаг. Например:
// Включаем std::ios::hex как единственный флаг std::ios::basefield std::cout.setf(std::ios::hex, std::ios::basefield); std::coutЭто также дает ожидаемый результат:
Использование setf() и unsetf() может быть неудобным, поэтому C++ предоставляет второй способ изменения параметров форматирования: манипуляторы. В манипуляторах хорошо то, что они достаточно умны, чтобы включать и выключать соответствующие флаги. Вот пример использования некоторых манипуляторов для изменения основания чисел:
std::coutЭта программа создает следующий вывод:
1b 1c 29В общем, пользоваться манипуляторами намного проще, чем устанавливать и сбрасывать флаги. Многие параметры доступны как через флаги, так и через манипуляторы (например, изменение основания числа), однако некоторые параметры доступны только через флаги или только через манипуляторы, поэтому важно знать, как использовать и то, и другое.
Полезные инструменты форматирования
Вот список некоторых наиболее полезных флагов, манипуляторов и функций-членов. Флаги находятся в классе std::ios , манипуляторы находятся в пространстве имен std , а функции-члены живут в классе std::ostream .
| Группа | Флаг | Назначение |
|---|---|---|
| std::ios::boolalpha | Если установлен, логические значения выводят как " true " или " false ". Если не установлен, логические значения выводят как 0 или 1. |
| Манипулятор | Назначение |
|---|---|
| std::boolalpha | Логические значения выводят как " true " или " false ". |
| std::noboolalpha | Логические значения выводят как 0 или 1 (по умолчанию). |
std::cout
1 0 true false 1 0 true false
| Группа | Флаг | Назначение |
|---|---|---|
| std::ios::showpos | Если установлен, перед положительными числами ставится +. |
| Манипулятор | Назначение |
|---|---|
| std::showpos | Добавляет к положительным числам префикс + |
| std::noshowpos | Не ставит перед положительными числами знак + |
std::cout
5 +5 5 +5
| Группа | Флаг | Назначение |
|---|---|---|
| std::ios::uppercase | Если установлен, используются буквы верхнего регистра. |
| Манипулятор | Назначение |
|---|---|
| std::uppercase | Использует буквы верхнего регистра |
| std::nouppercase | Использует буквы нижнего регистра |
std::cout
1.23457e+007 1.23457E+007 1.23457e+007 1.23457E+007
| Группа | Флаг | Назначение |
|---|---|---|
| std::ios::basefield | std::ios::dec | Печатает значения в десятичном формате (по умолчанию) |
| std::ios::basefield | std::ios::hex | Печатает значения в шестнадцатеричном формате |
| std::ios::basefield | std::ios::oct | Печатает значения в восьмеричном формате |
| std::ios::basefield | (нет) | Печатает значения в соответствии с начальными символами значения |
| Манипулятор | Назначение |
|---|---|
| std::dec | Печатает значения в десятичном формате |
| std::hex | Печатает значения в шестнадцатеричном формате |
| std::oct | Печатает значения в восьмеричном формате |
std::cout
27 27 33 1b 27 33 1b
К этому моменту вы должны увидеть взаимосвязь между настройкой форматирования с помощью флагов и с помощью манипуляторов. В будущих примерах мы будем использовать манипуляторы, если они доступны.
Точность, формат записи и десятичные точки
Используя манипуляторы (или флаги), можно изменить точность и формат отображения чисел с плавающей запятой. Есть несколько вариантов форматирования, которые комбинируются сложным образом, поэтому мы рассмотрим их подробнее.
| Группа | Флаг | Назначение |
|---|---|---|
| std::ios::floatfield | std::ios::fixed | Использует десятичную запись для чисел с плавающей запятой |
| std::ios::floatfield | std::ios::scientific | Использует экспоненциальную запись для чисел с плавающей запятой |
| std::ios::floatfield | (нет) | Использует десятичную запись для чисел с несколькими цифрами, в противном случае – экспоненциальную запись |
| std::ios::floatfield | std::ios::showpoint | Всегда показывать десятичную точку и завершающие нули для значений с плавающей запятой |
| Манипулятор | Назначение |
|---|---|
| std::fixed | Использует десятичную запись значений |
| std::scientific | Использует экспоненциальную запись значений |
| std::showpoint | Показывает десятичную точку и завершающие нули для значений с плавающей запятой |
| std::noshowpoint | Не показывать десятичную точку и завершающие нули для значений с плавающей запятой |
| std::setprecision(int) | Устанавливает точность чисел с плавающей запятой (определен в iomanip.h ) |
| Функция-член | Назначение |
|---|---|
| std::precision() | Возвращает текущую точность чисел с плавающей запятой |
| std::precision(int) | Устанавливает точность чисел с плавающей запятой и возвращает старую точность |
Если используется фиксированная или экспоненциальная запись, точность определяет, сколько знаков отображается в дробной части. Обратите внимание, что если точность меньше количества значащих цифр, число будет округлено.
std::cout
Дает следующий результат:
123.456 123.4560 123.45600 123.456000 123.4560000 1.235e+002 1.2346e+002 1.23456e+002 1.234560e+002 1.2345600e+002
Если не используется ни фиксированная, ни экспоненциальная запись, точность определяет, сколько следует отображать значащих цифр. Опять же, если точность меньше количества значащих цифр, число будет округлено.
std::cout
Дает следующий результат:
123 123.5 123.46 123.456 123.456
Используя манипулятор или флаг showpoint , вы можете заставить поток записывать десятичную точку и завершающие нули.
std::cout
Дает следующий результат:
123. 123.5 123.46 123.456 123.4560
Вот сводная таблица с еще несколькими примерами:
| Тип записи | Точность | 12345.0 | 0.12345 |
|---|---|---|---|
| Обычный | 3 | 1.23e+004 | 0.123 |
| 4 | 1.235e+004 | 0.1235 | |
| 5 | 12345 | 0.12345 | |
| 6 | 12345 | 0.12345 | |
| Показывать десятичную точку |
3 | 1.23e+004 | 0.123 |
| 4 | 1.235e+004 | 0.1235 | |
| 5 | 12345. | 0.12345 | |
| 6 | 12345.0 | 0.123450 | |
| Фиксированная запись |
3 | 12345.000 | 0.123 |
| 4 | 12345.0000 | 0.1235 | |
| 5 | 12345.00000 | 0.12345 | |
| 6 | 12345.000000 | 0.123450 | |
| Экспоненциальная запись |
3 | 1.235e+004 | 1.235e-001 |
| 4 | 1.2345e+004 | 1.2345e-001 | |
| 5 | 1.23450e+004 | 1.23450e-001 | |
| 6 | 1.234500e+004 | 1.234500e-001 |
Ширина, символы заполнения и выравнивание
Обычно при печати чисел числа печатаются без учета пространства вокруг них. Однако печать чисел можно выровнять по левому или правому краю. Для этого мы должны сначала определить ширину поля, которая определяет количество выходных мест печати символов, которые будут заниматься печатаемым значением. Если фактическое напечатанное число меньше ширины поля, оно будет выровнено по левому или правому краю (как указано). Если фактическое число больше ширины поля, оно не будет усечено – оно приведет к переполнению поля.
| Группа | Флаг | Назначение |
|---|---|---|
| std::ios::adjustfield | std::ios::internal | Выравнивает знак числа по левому краю, а значение – по правому краю |
| std::ios::adjustfield | std::ios::left | Выравнивание знака и значения по левому краю |
| std::ios::adjustfield | std::ios::right | Выравнивает знак и значение по правому краю (по умолчанию) |
| Манипулятор | Назначение |
|---|---|
| std::internal | Выравнивает знак числа по левому краю, а значение – по правому краю |
| std::left | Выравнивание знака и значения по левому краю |
| std::right | Выравнивает знак и значение по правому краю |
| std::setfill(char) | Устанавливает параметр как символ заполнения (определен в iomanip.h ) |
| std::setw(int) | Устанавливает ширину поля для ввода и вывода в значение параметра (определен в iomanip.h ) |
| Функция-член | Назначение |
|---|---|
| std::fill() | Возвращает текущий символ заполнения |
| std::fill(char) | Устанавливает символ заполнения и возвращает старый символ заполнения |
| std::width() | Возвращает текущую ширину поля |
| std::width(int) | Устанавливает новую ширину поля и возвращает старую ширину поля |
Чтобы использовать любое из этих средств форматирования, мы сначала должны установить ширину поля. Это можно сделать с помощью функции-члена width(int) или манипулятора setw() . Обратите внимание, что по умолчанию используется выравнивание по правому краю.
// выводим значение по умолчанию без ширины поля std::cout
Это дает следующий результат:
-12345 -12345 -12345 -12345 - 12345
Следует отметить, что setw() и width() влияют только на следующую инструкцию вывода. Они не постоянны, как некоторые другие флаги/манипуляторы.
Теперь давайте установим символ заполнения и выполним тот же пример:
std::cout.fill('*'); // выводим значение по умолчанию без ширины поля std::cout
Это дает следующий результат:
-12345 ****-12345 -12345**** ****-12345 -****12345
Обратите внимание, что все пустые места в поле заполнены символом заполнения.
Класс ostream и библиотека iostream содержат функции вывода, флаги и манипуляторы, которые могут быть полезны в зависимости от того, что вам нужно сделать. Как и в случае с классом istream , эти темы больше подходят для учебника или книги, посвященной стандартной библиотеке.