Урок №217. Функціонал класів ostream і ios. Форматування виводу

  Юрій  | 

  Оновл. 29 Кві 2021  | 

 14

На цьому уроці ми розглянемо функціонал класів ostream і ios в мові С++.

Примітка: Весь функціонал об’єктів, які працюють з потоками вводу/виводу, знаходиться в просторі імен std. Це означає, що вам потрібно або додавати префікс std:: до всіх об’єктів і функцій вводу/виводу, або використовувати в програмі рядок using namespace std;.

Форматування виводу

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

Є два способи управління параметрами форматування виводу:

   флаги — це логічні змінні, які можна включити/відключити;

   маніпулятори — це об’єкти, які поміщаються в потік і впливають на спосіб вводу/виводу даних.

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

Результат:

+30

Також можна включити відразу кілька флагів, використовуючи побітовий оператор АБО (|):

Щоб відключити флаг, використовуйте функцію unsetf():

Результат:

+30
31

Багато флагів належать до певних груп форматування. Група форматування — це група флагів, які задають аналогічні (іноді взаємовиключні) параметри форматування виводу. Наприклад, є група форматування basefield.

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

   oct (від англ. octal” = “вісімковий”) — вісімкова система числення;

   dec (від англ. decimal” = “десятковий”) — десяткова система числення;

   hex (від англ. hexadecimal” = “шістнадцятковий”) — шістнадцяткова система числення.

Ці флаги керують виводом цілочисельних значень. За замовчуванням встановлено флаг std::dec, тобто значення виводяться в десятковій системі числення. Спробуємо зробити наступне:

Результат:

30

Нічого не працює! Чому? Справа в тому, що setf() тільки включає флаги, він не настільки розумний, щоб одночасно відключати інші (взаємовиключні) флаги. Отже, коли ми включаємо std::hex, std::dec також включений і у нього більший пріоритет. Є два способи вирішення даної проблеми.

По-перше, ми можемо відключити std::dec, а потім включити std::hex:

Тепер вже результат той, що потрібно:

1e

Другий спосіб — використовувати варіацію функції setf(), яка приймає два параметри:

   перший параметр — це флаг, який потрібно включити/відключити;

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

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

Результат:

1e

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

Результат:

1e
1f
32

Загалом, використовувати маніпулятори набагато простіше, ніж включати/відключати флаги. Багато параметрів форматування можна змінювати як через флаги, так і через маніпулятори, але є і такі параметри форматування, які змінити можна або тільки через флаги, або тільки через маніпулятори.

Корисні флаги, маніпулятори і методи

Нижче ми розглянемо список найбільш корисних флагів, маніпуляторів і методів. Флаги знаходяться в класі 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 — перед позитивними числами не вказується знак +.

Наприклад:

Результат:

7
+7
7
+7

Флаг:

   uppercase — якщо включений, то використовуються заголовні букви.

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

   uppercase — використовуються заголовні букви.

   nouppercase — використовуються рядкові (малі) букви.

Наприклад:

Результат:

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

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

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

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

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

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

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

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

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

Наприклад:

Результат:

30
30
36
1e
30
36
1e

Тепер ви вже повинні розуміти зв’язок між флагами і маніпуляторами.

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

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

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

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

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

   showpoint — завжди відображається десяткова крапка і кінцеві нулі для чисел типу з плаваючою крапкою.

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

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

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

   showpoint — відображається десяткова крапка і кінцеві нулі чисел типу з плаваючою крапкою;

   noshowpoint — не відображаються десяткова крапка і кінцеві нулі чисел типу з плаваючою крапкою;

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

Методи:

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

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

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

Результат:

123.456
123.4560
123.45600
123.456000
123.4560000

1.235e+02
1.2346e+02
1.23456e+02
1.234560e+02
1.2345600e+02

Якщо не використовуються ні десятковий, ні експоненціальний запис чисел, то точність визначає, скільки значущих цифр відображатиметься. Наприклад:

Результат:

123
123.5
123.46
123.456
123.456

Використовуючи маніпулятор або флаг showpoint, ми можемо змусити програму виводити десяткову крапку і кінцеві нулі. Наприклад:

Результат:

123.
123.5
123.46
123.456
123.4560

Ширина поля, символи-заповнювачі і вирівнювання

Зазвичай числа виводяться без урахування простору навколо них. Проте, числа можна вирівнювати. Щоб це зробити, потрібно спочатку визначити ширину поля (тобто кількість простору (пробілів) навколо значень).

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

   internal — знак значення вирівнюється по лівому краю, а саме значення — по правому краю;

   left — значення і його знак вирівнюються по лівому краю;

   right — значення і його знак вирівнюються по правому краю.

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

   internal — знак значення вирівнюється по лівому краю, а саме значення — по правому краю;

   left — значення і його знак вирівнюються по лівому краю;

   right — значення і його знак вирівнюються по правому краю;

   setfill(char) — вказуємо символ-заповнювач;

   setw(int) — вказуємо ширину поля.

Методи:

   fill() — повертаємо поточний символ-заповнювач;

   fill(char) — вказуємо новий символ-заповнювач;

   width() — повертаємо поточну ширину поля;

   width(int) — вказуємо ширину поля.

Щоб використовувати будь-який з вищеперерахованих об’єктів, потрібно спочатку встановити ширину поля. Це робиться за допомогою методу width(int) або маніпулятора setw(). Зверніть увагу, за замовчуванням при використанні ширини поля значення вирівнюються по правому краю. Наприклад:

Результат:

Тепер давайте задамо свій власний символ-заповнювач:

Результат:

-12345
****-12345
-12345****
****-12345
-****12345

Зверніть увагу, весь порожній простір навколо чисел заповнений * (символом-заповнювачем).

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

Оцінити статтю:

1 Зірка2 Зірки3 Зірки4 Зірки5 Зірок (Немає Оцінок)
Loading...

Залишити відповідь

Ваш E-mail не буде опублікований. Обов'язкові поля відмічені *