Ostream c что это

от admin

Потоки и система ввода-вывода

Все инструменты для работы с системой ввода-вывода и потоками в языке С++ определены в стандартной библиотеке. Заголовочный файл iostream определяет следующие базовые типы для работы с потоками:

istream и wistream : читают данные с потока

ostream и wostream : записывают данные в поток

iostream и wiostream : читают и записывают данные в поток

Для каждого типа определен его двойник, который начинается на букву w и который предназначен для поддержки данных типа wchar_t.

Эти типы являются базовыми для других классов, управляющих потоками ввода-вывода.

Объект типа ostream получает значения различных типов, преобразует их в последовательность символов и передает их через буфер в определенное место для вывода (консоль, файл, сетевые интерфейсы и т.д.)

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

Поток ввода istream в С++

По умолчанию в стандартной библиотеке определены объекты этих классов — cout , cin , cerr , которые работают с консолью.

Запись в поток

Для записи данных в поток ostream применяется оператор << . Этот оператор получает два операнда. Левый операнд представляет объект типа ostream, а правый операнд — значение, которое надо вывести в поток.

К примеру, по умолчанию стандартная библиотека C++ предоставляет объект cout , который представляет тип ostream и позволяет выводить данные на консоль:

Так как оператор << возвращает левый операнд — cout, то с помощью цепочки операторов мы можем передать на консоль несколько значений:

Чтение данных

Для чтения данных из потока применяется оператор ввода >> , который принимает два операнда. Левый операнд представляет поток istream, с которого производится считывание, а правый операнд — объект, в который считываются данные.

Для чтения с консоли применяется объект cin , который представляет тип istream.

Однако такой способ не очень подходит для чтения строк с консоли особенно когда считываемая строка содержит пробельные символы. В этом случае лучше использовать встроенную функцию getline() , которая в качестве параметра принимает поток istream и переменную типа string, в которую надо считать данные:

Консольный вывод данной программы:

Вывод ошибок

Для вывода сообщения об ошибке на консоль применяется объект cerr , который представляет объект типа ostream:

Потоки символов wchar_t

Для работы с потоками данных типов wchar_t в стандартной библиотеке определены объекты wcout (тип wostream), wcerr (тип wostream) и wcin (тип wistream), которые являются аналогами для объектов cout, cerr и cin и работают аналогично

Урок №209. Функционал классов ostream и ios. Форматирование вывода

На этом уроке мы рассмотрим функционал классов ostream и ios в языке С++.

Примечание: Весь функционал объектов, которые работают с потоками ввода/вывода, находится в пространстве имен std. Это означает, что вам нужно либо добавлять префикс std:: ко всем объектам и функциям ввода/вывода, либо использовать в программе строку using namespace std; .

Форматирование вывода

Оператор вставки (вывода) << используется для помещения информации в выходной поток. А как мы уже знаем из урока о потоках, классы istream и ostream являются дочерними классу ios . Одной из задач ios (и ios_base ) является управление параметрами форматирования вывода.

Есть два способа управления параметрами форматирования вывода:

флаги — это логические переменные, которые можно включить/выключить;

манипуляторы — это объекты, которые помещаются в поток и влияют на способ ввода/вывода данных.

Для включения флага используйте функцию setf() с соответствующим флагом в качестве параметра. Например, по умолчанию C++ не выводит знак + перед положительными числами. Однако, используя флаг std::showpos, мы можем это изменить:

Также можно включить сразу несколько флагов, используя побитовый оператор ИЛИ ( | ):

Чтобы отключить флаг, используйте функцию unsetf():

Многие флаги принадлежат к определенным группам форматирования. Группа форматирования — это группа флагов, которые задают аналогичные (иногда взаимоисключающие) параметры форматирования вывода. Например, есть группа форматирования basefield.

Флаги группы форматирования basefield:

oct (от англ. «octal» = «восьмеричный») — восьмеричная система счисления;

dec (от англ. «decimal» = «десятичный») — десятичная система счисления;

hex (от англ. «hexadecimal» = «шестнадцатеричный») — шестнадцатеричная система счисления.

Эти флаги управляют выводом целочисленных значений. По умолчанию установлен флаг std::dec, т.е. значения выводятся в десятичной системе счисления. Попробуем сделать следующее:

Ничего не работает! Почему? Дело в том, что setf() только включает флаги, он не настолько умен, чтобы одновременно отключать другие (взаимоисключающие) флаги. Следовательно, когда мы включаем std::hex, std::dec также включен и у него приоритет выше. Есть два способа решения данной проблемы.

Во-первых, мы можем отключить std::dec, а затем включить std::hex:

Теперь уже результат тот, что нужно:

Второй способ — использовать вариацию функции setf(), которая принимает два параметра:

первый параметр — это флаг, который нужно включить/выключить;

второй параметр — группа форматирования, к которой принадлежит флаг.

При использовании этой вариации функции setf() все флаги, принадлежащие группе форматирования, отключаются, а включается только передаваемый флаг. Например:

Язык C++ также предоставляет еще один способ изменения параметров форматирования: манипуляторы. Фишка манипуляторов в том, что они достаточно умны, чтобы одновременно включать и выключать соответствующие флаги. Например:

В общем, использовать манипуляторы гораздо проще, нежели включать/выключать флаги. Многие параметры форматирования можно изменять как через флаги, так и через манипуляторы, но есть и такие параметры форматирования, которые изменить можно либо только через флаги, либо только через манипуляторы.

Полезные флаги, манипуляторы и методы

Ниже мы рассмотрим список наиболее полезных флагов, манипуляторов и методов. Флаги находятся в классе ios , манипуляторы — в пространстве имен std, а методы — в классе ostream .

Флаг:

boolalpha — если включен, то логические значения выводятся как true / false . Если выключен, то логические значения выводятся как 0 / 1 .

Манипуляторы:

boolalpha — логические значения выводятся как true / false .

noboolalpha — логические значения выводятся как 0 / 1 .

1 0
true false
1 0
true false

Флаг:

showpos — если включен, то перед положительными числами указывается знак + .

Манипуляторы:

showpos — перед положительными числами указывается знак + .

noshowpos — перед положительными числами не указывается знак + .

Флаг:

uppercase — если включен, то используются заглавные буквы.

Манипуляторы:

uppercase — используются заглавные буквы.

nouppercase — используются строчные буквы.

1.23457e+007
1.23457E+007
1.23457e+007
1.23457E+007

Флаги группы форматирования basefield:

dec — значения выводятся в десятичной системе счисления;

hex — значения выводятся в шестнадцатеричной системе счисления;

oct — значения выводятся в восьмеричной системе счисления.

Манипуляторы:

dec — значения выводятся в десятичной системе счисления;

hex — значения выводятся в шестнадцатеричной системе счисления;

oct — значения выводятся в восьмеричной системе счисления.

Теперь вы уже должны понимать связь между флагами и манипуляторами.

Точность, запись чисел и десятичная точка

Используя манипуляторы (или флаги), можно изменить точность и формат вывода значений типа с плавающей точкой.

Флаги группы форматирования floatfield:

fixed — используется десятичная запись чисел типа с плавающей точкой;

scientific — используется экспоненциальная запись чисел типа с плавающей точкой;

showpoint — всегда отображается десятичная точка и конечные нули для чисел типа с плавающей точкой.

Манипуляторы:

fixed — используется десятичная запись значений;

scientific — используется экспоненциальная запись значений;

showpoint — отображается десятичная точка и конечные нули чисел типа с плавающей точкой;

noshowpoint — не отображаются десятичная точка и конечные нули чисел типа с плавающей точкой;

setprecision(int) — задаем точность для чисел типа с плавающей точкой.

Методы:

precision() — возвращаем текущую точность для чисел типа с плавающей точкой;

precision(int) — задаем точность для чисел типа с плавающей точкой.

Если используется десятичная или экспоненциальная запись чисел, то точность определяет количество цифр после запятой/точки. Обратите внимание, если точность меньше количества значащих цифр, то число будет округлено. Например:

Глава 8

Язык C++ не обеспечивает средств для ввода/вывода. Ему это и не нужно; такие средства легко и элегантно можно создать с помощью самого языка. Описанная здесь стандартная библиотека потокового ввода/вывода обеспечивает гибкий и эффективный с гарантией типа метод обработки символьного ввода целых чисел, чисел с плавающей точкой и символьных строк, а также простую модель ее расширения для обработки типов, определяемых пользователем. Ее пользовательский интерфейс находится в . В этой главе описывается сама библиотека, некоторые способы ее применения и методы, которые использовались при ее реализации.

8.1 Введение

Разработка и реализация стандартных средств ввода/вывода для языка программирования зарекомендовала себя как заведомо трудная работа. Традиционно средства ввода/вывода разрабатывались исключительно для небольшого числа встроенных типов данных. Однако в C++ программах обычно используется много типов, определенных пользователем, и нужно обрабатывать ввод и вывод также и значений этих типов. Очевидно, средство ввода/вывода должно быть простым, удобным, надежным в употреблении, эффективным и гибким, и ко всему прочему полным. Ничье решение еще не смогло угодить всем, поэтому у пользователя должна быть возможность задавать альтернативные средства ввода/вывода и расширять стандартные средства ввода/вывода применительно к требованиям приложения.
C++ разработан так, чтобы у пользователя была возможность определять новые типы столь же эффективные и удобные, сколь и встроенные типы. Поэтому обоснованным является требование того, что средства ввода/вывода для C++ должны обеспечиваться в C++ с применением только тех средств, которые доступны каждому программисту. Описываемые здесь средства ввода/вывода представляют собой попытку ответить на этот вызов.
Средства ввода/вывода связаны исключительно с обработкой преобразования типизированных объектов в последовательности символов и обратно. Есть и другие схемы ввода/вывода, но эта является основополагающей в системе UNIX, и большая часть видов бинарного ввода/вывода обрабатывается через рассмотрение символа просто как набор бит, при этом его общепринятая связь с алфавитом игнорируется. Тогда для программиста ключевая проблема заключается в задании соответствия между типизированным объектом и принципиально не типизированной строкой.
Обработка и встроенных и определенных пользователем типов однородным образом и с гарантией типа достигается с помощью одного перегруженного имени функции для набора функций вывода. Например:
Тип параметра определяет то, какая из функций put будет вызываться для каждого параметра. Это решение применялось в нескольких языках. Однако ему недостает лаконичности. Перегрузка операции , но значения «меньше» и «больше» настолько прочно вросли в сознание людей, что новые операции ввода/вывода во всех реальных случаях оказались нечитаемыми. Помимо этого, » > к такого рода проблемам не приводят, они асимметричны в том смысле, что их можно проассоциировать с «в» и «из», а приоритет > («взять из») для небольшого множества стандартных типов. Функция operator>> может определяться для типа, определяемого пользователем.

8.4.1 Ввод Встроенных Типов

Класс istream определяется так:
Функции ввода определяются в таком духе:
Пропуск определяется как стандартный пропуск в C, через вызов isspase() в том виде, как она определена в (пробел, табуляция, символ новой строки, перевод формата и возврат каретки).
В качестве альтернативы можно использовать функции get():
Они обрабатывают символы пропуска так же, как остальные символы. Функция istream::get(char) читает один и тот же символ в свой параметр; другая istream::get читает не более n символов в вектор символов, начинающийся в p. Необязательный третий параметр используется для задания символа остановки (иначе, терминатора или ограничителя), то есть этот символ читаться не будет. Если будет встречен символ ограничитель, он останется как первый символ потока. По умолчанию вторая функция get будет читать самое большее n символов, но не больше чем одну строку, ‘\n’ является ограничителем по умолчанию. Необязательный третий параметр задает символ, который читаться не будет. Например:
будет читать в buf не более 256 символов, а если встретится табуляция (‘\t’), то это приведет к возврату из get. В этом случае следующим символом, который будет считан из cin, будет ‘\t’.
Стандартный заголовочный файл определяет несколько функций, которые могут оказаться полезными при осуществлении ввода:
Все кроме isascii() реализуются внешне одинаково, с применением символа в качестве индекса в таблице атрибутов символов. Поэтому такие выражения, как
не только утомительно пишутся и чреваты ошибками (на машине с набором символов EBCDIC оно будет принимать неалфавитные символы), они также и менее эффективны, чем применение стандартной функции:

8.4.2 Состояния Потока

Каждый поток (istream или ostream) имеет ассоциированное с ним состояние, и обработка ошибок и нестандартных условий осуществляется с помощью соответствующей установки и проверки этого состояния.
Поток может находиться в одном из следующих состояний:
Если состояние _good или _eof, значит последняя операция ввода прошла успешно. Если состояние _good, то следующая операция ввода может пройти успешно, в противном случае она закончится неудачей. Другими словами, применение операции ввода к потоку, который не находится в состоянии _good, является пустой операцией. Если делается попытка читать в переменную v, и операция оканчивается неудачей, значение v должно остаться неизменным (оно будет неизменным, если v имеет один из тех типов, которые обрабатываются функциями членами istream или ostream). Отличия между состояниями _fail и _bad очень незначительно и представляет интерес только для разработчиков операций ввода. В состоянии _fail предполагается, что поток не испорчен и никакие символы не потеряны. В состоянии _bad может быть все что угодно.
Состояние потока можно проверять например так:
Для любой переменной z типа, для которого определены операции >, копирующий цикл можно написать так:
Например, если z — вектор символов, этот цикл будет брать стандартный ввод и помещать его в стандартный вывод по одному слову (то есть, последовательности символов без пробела) на строку.
Когда в качестве условия используется поток, происходит проверка состояния потока и эта проверка проходит успешно (то есть, значение условия не ноль) только если состояние _good. В частности, в предыдущем цикле проверялось состояние istream, которое возвращает cin>>z. Чтобы обнаружить, почему цикл или проверка закончились неудачно, можно исследовать состояние. Такая проверка потока реализуется операцией преобразования (#6.3.2).
Делать проверку на наличие ошибок каждого ввода или вывода действительно не очень удобно, и обычно источником ошибок служит программист, не сделавший этого в том месте, где это существенно. Например, операции вывода обычно не проверяются, но они могут случайно не сработать. Парадигма потока ввода/вывода построена так, чтобы когда в C++ появится (если это произойдет) механизм обработки исключительных ситуаций (как средство языка или как стандартная библиотека) его будет легко применить для упрощения и стандартизации обработки ошибок в потоках ввода/вывода.

Читать:
Как из xml файла составить самостоятельно таблицу

8.4.3 Ввод Типов, Определяемых Пользователем

Ввод для пользовательского типа может определяться точно так же, как вывод, за тем исключением, что для операции ввода важно, чтобы второй параметр был ссылочного типа. Например:
Несмотря на то, что не хватает кода обработки ошибок, большую часть видов ошибок это на самом деле обрабатывать будет. Локальная переменная c инициализируется, чтобы ее значение не оказалось случайно ‘(‘ после того, как операция окончится неудачно. Завершающая проверка состояния потока гарантирует, что значение параметра a будет изменяться только в том случае, если все идет хорошо.
Операция установки состояния названа clear() (очистить), потому что она чаще всего используется для установки состояния потока заново как _good. _good является значением параметра по умолчанию и для istream::clear(), и для ostream::clear().
Над операциями ввода надо поработать еще. Было бы, в частности, замечательно, если бы можно было задавать ввод в терминах шаблона (как в языках Снобол и Икон), а потом проверять, прошла ли успешна вся операция ввода. Такие операции должны были бы, конечно, обеспечивать некоторую дополнительную буферизацию, чтобы они могли восстанавливать поток ввода в его исходное состояние после неудачной попытки распознавания.

8.4.4 Инициализация Потоков Ввода

Естественно, тип istream, так же как и ostream, снабжен конструктором:
Параметр sk задает, должны пропускаться пропуски или нет. Параметр t (необязательный) задает указатель на ostream, к которому прикреплен istream. Например, cin прикреплен к cout; это значит, что перед тем, как попытаться читать символы из своего файла, cin выполняет
С помощью функции istream::tie() можно прикрепить (или открепить, с помощью tie(0)) любой ostream к любому istream. Например:
Когда используется буферизованный ввод (как это происходит по умолчанию), пользователь не может набрав только одну букву ожидать отклика. Система ждет появления символа новой строки. y_or_n() смотрит на первый символ строки, а остальные игнорирует.
Символ можно вернуть в поток с помощью функции istream::putback(char). Это позволяет программе «заглядывать вперед» в поток ввода.

8.5 Работа со Строками

Можно осуществлять действия, подобные вводу/выводу, над символьным вектором, прикрепляя к нему istream или ostream. Например, если вектор содержит обычную строку, завершающуюся нулем, для печати слов из этого вектора можно использовать приведенный выше копирующий цикл:
Завершающий нулевой символ в этом случае интерпретируется как символ конца файла.
В помощью ostream можно отформатировать сообщения, которые не нужно печатать тотчас же:
Такая операция, как do_something, может писать в поток ost, передавать ost своим подоперациям и т.д. с помощью стандартных операций вывода. Нет необходимости делать проверку не переполнение, поскольку ost знает свою длину и когда он будет переполняться, он будет переходить в состояние _fail. И, наконец, display может писать сообщения в «настоящий» поток вывода. Этот метод может оказаться наиболее полезным, чтобы справляться с ситуациями, в которых окончательное отображение данных включает в себя нечто более сложное, чем работу с традиционным построчным устройством вывода. Например, текст из ost мог бы помещаться в располагающуюся где-то на экране область фиксированного размера.

8.6 Буферизация

При задании операций ввода/вывода мы никак не касались типов файлов, но ведь не все устройства можно рассматривать одинаково с точки зрения стратегии буферизации. Например, для ostream, подключенного к символьной строке, требуется буферизация другого вида, нежели для ostream, подключенного к файлу. С этими проблемами можно справиться, задавая различные буферные типы для разных потоков в момент инициализации (обратите внимание на три конструктора класса ostream). Есть только один набор операций над этими буферными типами, поэтому в функциях ostream нет кода, их различающего. Однако функции, которые обрабатывают переполнение сверху и снизу, виртуальные. Этого достаточно, чтобы справляться с необходимой в данное время стратегией буферизации. Это также служит хорошим примером применения виртуальных функций для того, чтобы сделать возможной однородную обработку логически эквивалентных средств с различной реализацией. Описание буфера потока в выглядит так:
Обратите внимание, что здесь определяются указатели, необходимые для работы с буфером, поэтому обычные посимвольные действия можно определить (только один раз) в виде максимально эффективных inline- функций. Для каждой конкретной стратегии буферизации необходимо определять только функции переполнения overflow() и underflow(). Например:

8.7 Эффективность

Можно было бы ожидать, что раз ввод/вывод определен с помощью общедоступных средств языка, он будет менее эффективен, чем встроенное средство. На самом деле это не так. Для действий вроде «поместить символ в поток» используются inline-функции, единственные необходимые на этом уровне вызовы функций возникают из-за переполнения сверху и снизу. Для простых объектов (целое, строка и т.п.) требуется по одному вызову на каждый. Как выясняется, это не отличается от прочих средств ввода/вывода, работающих с объектами на этом уровне.

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 , мы можем изменить это поведение:

Это приводит к следующему выводу:

Можно включить сразу несколько флагов ios с помощью оператора ИЛИ ( | ):

Чтобы отключить флаг, используйте функцию unsetf() :

Это приводит к следующему выводу:

Есть еще одна хитрость при использовании setf() , о которой следует упомянуть. Многие флаги принадлежат группам, называемым группами форматирования. Группа форматирования – это группа флагов, которые управляют аналогичными (иногда взаимоисключающими) параметрами форматирования. Например, группа форматирования с именем basefield содержит флаги oct , dec и hex , которые управляют основанием целочисленных значений. По умолчанию установлен флаг dec . Следовательно, если мы сделаем это:

То получим такой вывод:

Не сработало! Причина в том, что setf() только включает флаги – этого недостаточно, чтобы отключить взаимоисключающие флаги. Следовательно, когда мы включили std::hex , std::ios::dec всё еще был включен, а std::ios::dec явно имеет приоритет. Есть два способа обойти эту проблему.

Во-первых, мы можем отключить std::ios::dec , чтобы был установлен только std::hex :

Теперь мы получаем ожидаемый результат:

Второй способ – использовать другую форму setf() , которая принимает два параметра: первый параметр – это флаг, который нужно установить, а второй – это группа форматирования, к которой он принадлежит. При использовании этой формы setf() все флаги, принадлежащие группе, отключаются, и включается только переданный флаг. Например:

Это также дает ожидаемый результат:

Использование setf() и unsetf() может быть неудобным, поэтому C++ предоставляет второй способ изменения параметров форматирования: манипуляторы. В манипуляторах хорошо то, что они достаточно умны, чтобы включать и выключать соответствующие флаги. Вот пример использования некоторых манипуляторов для изменения основания чисел:

Эта программа создает следующий вывод:

В общем, пользоваться манипуляторами намного проще, чем устанавливать и сбрасывать флаги. Многие параметры доступны как через флаги, так и через манипуляторы (например, изменение основания числа), однако некоторые параметры доступны только через флаги или только через манипуляторы, поэтому важно знать, как использовать и то, и другое.

Полезные инструменты форматирования

Вот список некоторых наиболее полезных флагов, манипуляторов и функций-членов. Флаги находятся в классе std::ios , манипуляторы находятся в пространстве имен std , а функции-члены живут в классе std::ostream .

Группа Флаг Назначение
std::ios::boolalpha Если установлен, логические значения выводят как " true " или " false ". Если не установлен, логические значения выводят как 0 или 1.
Манипулятор Назначение
std::boolalpha Логические значения выводят как " true " или " false ".
std::noboolalpha Логические значения выводят как 0 или 1 (по умолчанию).
Группа Флаг Назначение
std::ios::showpos Если установлен, перед положительными числами ставится +.
Манипулятор Назначение
std::showpos Добавляет к положительным числам префикс +
std::noshowpos Не ставит перед положительными числами знак +
Группа Флаг Назначение
std::ios::uppercase Если установлен, используются буквы верхнего регистра.
Манипулятор Назначение
std::uppercase Использует буквы верхнего регистра
std::nouppercase Использует буквы нижнего регистра
Группа Флаг Назначение
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::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) Устанавливает точность чисел с плавающей запятой и возвращает старую точность

Если используется фиксированная или экспоненциальная запись, точность определяет, сколько знаков отображается в дробной части. Обратите внимание, что если точность меньше количества значащих цифр, число будет округлено.

Дает следующий результат:

Если не используется ни фиксированная, ни экспоненциальная запись, точность определяет, сколько следует отображать значащих цифр. Опять же, если точность меньше количества значащих цифр, число будет округлено.

Дает следующий результат:

Используя манипулятор или флаг showpoint , вы можете заставить поток записывать десятичную точку и завершающие нули.

Дает следующий результат:

Вот сводная таблица с еще несколькими примерами:

Тип записи Точность 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() . Обратите внимание, что по умолчанию используется выравнивание по правому краю.

Это дает следующий результат:

Следует отметить, что setw() и width() влияют только на следующую инструкцию вывода. Они не постоянны, как некоторые другие флаги/манипуляторы.

Теперь давайте установим символ заполнения и выполним тот же пример:

Это дает следующий результат:

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

Класс ostream и библиотека iostream содержат функции вывода, флаги и манипуляторы, которые могут быть полезны в зависимости от того, что вам нужно сделать. Как и в случае с классом istream , эти темы больше подходят для учебника или книги, посвященной стандартной библиотеке.

Похожие статьи