Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
+ООП_Навч_посібник.doc
Скачиваний:
7
Добавлен:
01.07.2025
Размер:
6.58 Mб
Скачать

19.4. Форматоване введення-виведення даних

Дотепер під час введення або виведення інформації в наведених вище прикладах програм діяли параметри форматування, які за замовчуванням використовує С++-система введення-виведення. Але програміст може сам керувати форматом представлення даних, причому двома способами. Перший спосіб передбачає використання функцій-членів класу ios, а другий –| функцій спеціального типу, що іменуються маніпуляторами (manipulator). У цьому підрозділі почнемо засвоєння можливостей форматування даних з функцій-членів класу ios, а завершимо – створенням власних маніпуляторних функцій.

19.4.1. Форматування даних з використанням функцій-членів класу ios

У C++-системі введення-виведення кожен потік пов'язаний з набором прапорців, які керують процесом форматування даних. У класі ios оголошується перерахунок fmtflags, у якому визначено стандартні значення прапорців форматування2 (табл. 19.2).

Табл. 19.2. Стандартні С++-значення прапорців форматування

adjustfield

floatfield

right

skipws

basefield

hex

scientific

unitbuf

boolalpha

internal

showbase

uppercase

dec

left

showpoint

fixed

oct

showpos

Ці значення використовуються для встановлення або скидання прапорців форматування за допомогою таких функцій: setf() і unsetf(). Під час використання старого компілятора може так статися, що він не зможе визначити тип перерахунку fmtflags. У цьому випадку прапорці форматування кодуватимуться як цілочисельні long-значення.

1. Якщо прапорець skipws встановлено, то при потоковому введенні даних провідні "пропускні" символи, або символи пропуску (тобто пропуски, символи табуляції та нового рядка), відкидаються. Якщо ж прапорець skipws скинуто, то пропускні символи не відкидаються.

2. Якщо встановлено прапорець left, то дані, що виводяться, вирівнюються по лівому краю, а якщо встановлено прапорець right – по правому. Якщо встановлено прапорець internal, то числове значення доповнюється пропусками, якими заповнюється поле між ним і знаком числа або символом основи системи числення. Якщо жоден з цих прапорців не встановлено, то результат вирівнюється по правому краю за замовчуванням.

3. За замовчуванням числові значення виводяться у десятковій системі числення. Проте основу системи числення можна змінити. Встановлення прапорця oct приведе до виведення результату у вісімковому представленні, а встановлення прапорця hex – в шістнадцятковому. Щоб під час відображення результату повернутися до десяткової системи числення, достатньо встановити прапорець dec.

4. Встановлення прапорця showbase приводить до відображення позначення основи системи числення, у якій представляються числові значення. Наприклад, якщо використовується шістнадцяткове представлення, то значення 1F буде відображено як 0x1F.

5. За замовчуванням під час використання експоненціального представлення чисел відображається рядковий варіант букви "е". Окрім того, під час відображення шістнадцяткового значення використовують також рядкову букву "х". Після встановлення прапорця uppercase відображається прописний варіант цих символів.

6. Встановлення прапорця showpos викликає відображення провідного знаку "плюс" перед позитивними значеннями.

7. Встановлення прапорця showpoint приводить до відображення десяткової крапки і хвостових нулів для всіх чисел з плинною крапкою – потрібні вони чи ні.

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

9. При встановленому прапорці unitbuf вміст буфера скидається на диск після кожної операції виведення даних.

10. Якщо встановлено прапорець boolalpha, то значення булевого типу можна вводити або виводити, використовуючи ключові слова true і false.

Оскільки часто доводиться звертатися до полів oct, dec і hex, то на них допускається колективне посилання ios::basefield. Аналогічно поля left, right і internal можна узагальнено назвати ios::adjustfield. Нарешті, поля scientific і fixed можна назвати ios::floatfield.

Щоб встановити прапорці форматування, необхідно звернутися до функції setf().

Для встановлення будь-якого прапорця використовується функція setf(), яка є членом класу ios. Ось як виглядає її формат:

fmtflags setf(fmtflags flags);

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

stream.setf(ios::showbase);

У цьому записі елемент stream означає потік, параметри форматування якого Ви хочете змінити. Звернемо Вашу увагу на використання префікса ios:: для уточнення належності параметра showbase. Оскільки параметр showbase представляє собою перераховану константу, що визначається у класі ios, то під час звернення до неї необхідно вказувати ім'я класу ios. Цей принцип стосується всіх прапорців форматування. У наведеному нижче коді програми функція setf() використовують для встановлення прапорців showpos і scientific.

#include <iostream> // Для потокового введення-виведення

using namespace std; // Використання стандартного простору імен

int main()

{

cout.setf(ios::showpos); // Відображ. знаку "+" перед позит. знач.

cout.setf(ios::scientific); // Відображ. чисел в експоненц. вигляді

cout << 123 << " " << 123.23 << " ";

getch(); return 0;

}

Ось як виглядають результати виконання цієї програми:

+123 +1.232300е+002

За допомогою операції АБО можна встановити відразу декілька потрібних прапорців форматування в одному виклику функції setf(). Наприклад, попередню програму можна скоротити, об'єднавши за допомогою АБО прапорці scientific і showpos, оскільки у цьому випадку буде виконуватися тільки одне звернення до функції setf():

//Відображ. чисел в експоненц. вигляді або знаку "+" перед позит. знач.

cout.setf(ios::scientific || ios::showpos);

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

void unsetf(fmtflags flags);

Для скидання прапорців форматування використовується функція unsetf().

У цьому випадку будуть очищені прапорці, що задаються параметром flags. При цьому всі інші прапорці залишаються у попередньому стані.

Щоб отримати поточні установки прапорців форматування очікуваного результату, використовується функція flags().

Для того, щоб дізнатися про поточні установки прапорців форматування, потрібно скористатися функцією flags(), прототип якої має такий вигляд:

fmtflags flags();

Ця функція повертає поточні значення прапорців форматування для потоку, що викликається.

Під час використання наведеного нижче формату виклику функції flags() встановлюються значення прапорців форматування відповідно до вмісту параметра flags і повертаються їх попередні значення:

fmtflags flags(fmtflags flags);

Щоб зрозуміти, як працюють функції flags() і unsetf(), розглянемо детально наведену нижче програму. Вона містить функцію showflags(), яка відображає поточний стан прапорців форматування.

Код програми 19.4. Демонстрація механізму використання функцій flags() і unsetf()

#include <iostream> // Для потокового введення-виведення

using namespace std; // Використання стандартного простору імен

void showflags(ios::fmtflags f); // Відображення поточн. стану прапорців

int main()

{

ios::fmtflags f; // Оголошення параметру для пот. стану прапорців

f = cout.flags(); // Отримання поточного стану прапорців

showflags(f); // Відображення поточного стану прапорців

cout.setf(ios::showpos); // Відображ. знаку "+" перед позит. знач.

cout.setf(ios::scientific); //Відображ. чисел в експоненц. вигляді

f = cout.flags(); // Отримання поточного стану прапорців

showflags(f); // Відображення поточн. стану прапорців

// Скидання прапорця, що відображає числа в експоненц. вигляді

cout.unsetf(ios::scientific);

f = cout.flags(); // Отримання поточного стану прапорців

showflags(f); // Відображення поточн. стану прапорців

getch(); return 0;

}

void showflags(ios::fmtflags f) // Відображення поточн. стану прапорців

{

long i;

for(i=0x4000; i; i = i >> 1)

if(i & f) cout << "1 ";

else cout << "0 ";

cout << "\n";

}

У процесі виконання ця програма відображає на екрані такі результати1:

0 0 0 0 0 1 0 0 0 0 0 0 0 0 1

0 0 1 0 0 1 0 0 0 1 0 0 0 0 1

0 0 0 0 0 1 0 0 0 1 0 0 0 0 1

У наведеному вище коді програми зверніть увагу на те, що тип fmtflags вказано з префіксом ios::. Йдеться про те, що тип fmtflags визначено у класі ios. У загальному випадку під час використання імені типу або перерахованої константи, визначеної у деякому класі, необхідно вказувати відповідне ім'я разом з іменем класу.