Зміст теми. Загальна характеристика системи вводу-виводу С++. Стандартні потоки вводу-виводу. Стандартний потік виводу помилок. Маніпулятори потоку.
Потік – це абстрактне поняття, що відноситься до будь-якого перенесення даних від джерела до приймача. За видом пристроїв, з якими працює потік, можна розділити потоки на стандартні, файлові і строкові.
Стандартні потоки призначені для передачі даних від клавіатури і на екран дисплея. Файлові потоки для обміну інформацією з файлами на зовнішніх носіях даних (наприклад, дисках), а строкові потоки – для роботи з масивами символів в оперативній пам'яті.
Для створення стандартних потоків у мові С++ існують наступні класи:
istream – клас вхідних потоків;
ostream – клас вихідних потоків;
iostream – клас двонаправлених (вхідних і вихідних) потоків.
Клас ios є базовим класом для потоків. Частину ієрархії класів потоків вводу/виводу з класами обробки файлів наведено на рисунку 1.
Рисунок 1– Частина ієрархії класів потоків вводу/виводу з класами обробки файлів
Заголовний файл <iostream.h> містить, окрім опису класів введення/виведення, чотири об'єкти.
Таблиця – Об'єкти, які оголошені у файлі <iostream.h>
Об'єкт (потік) |
Клас |
Опис |
cin |
istreаm |
Зв'язується з клавіатурою (стандартним буферизуючим введенням) |
cout |
ostreаm |
Зв'язується з екраном (стандартним буферизуючим виводом) |
cerr |
ostreаm |
Зв'язується з екраном (стандартним небуферизуючим виводом), куди направляються повідомлення про помилки |
clog |
ostreаm |
Зв'язується з екраном (стандартним буферизуючим виводом), куди направляються повідомлення про помилки |
Для позначення виводу використовується операція (<<), яка називається операцією помістити в потік. Для позначення введення використовується операція (>>), яка називається операцією узяти з потоку. Ці операції застосовуються до об'єктів стандартних потоків cin, сout, cerr, clog і зазвичай використовуються також з об'єктами потоків, тип яких визначений користувачем. Для використання у програмі стандартних потоків необхідно включати файл iostream.h.
Кожна з операцій << і >> може бути використана у зчепленій формі. Багатократні операції помістити в потік або узяти з потоку виконуються в тій послідовності, в якій вони записані. Наприклад:
int x=10;
cout << «Змінна х має значення » << x ; // зчеплена форма операції <<
Другий рядок слід читати таким чином: помістити в стандартний потік виводу (тобто вивести на екран) напис «Змінна х має значення » і помістити в стандартний потік виводу значення змінної х.
int с;
float b;
cin>>с>>b;
Третій рядок слід читати таким чином: узяти із стандартного потоку введення (тобто ввести з клавіатури) два значення і помістити перше в змінну с, а друге – в змінну b.
В ланцюжок операцій поміщення в потік і одержання з потоку можна включати функції, які називаються маніпуляторами. Маніпулятори потоків вирішують задачі форматування, тобто завдання ширини полів, завдання точності, вставку у вихідний потік символу нового рядка і т.д. Використання маніпуляторів вимагає включення заголовного файлу <iomanip.h>. Наприклад:
cout << «с=» << с <<endl << «b=» << b;
Маніпулятор endl вставляє у вихідний потік символ нового рядка, тому напис «b=» буде виведено на новому рядку.
Управляти точністю чисел з комою, що виводяться, тобто числом розрядів праворуч від десяткової крапки, можна за допомогою маніпулятора setprecision. Точність задається в дужках. Точність 0 має особливе значення, вона відновлює точність за замовчанням, що дорівнює 6. Встановлення точності діє для всіх подальших операцій виводу до тих пір, поки не буде проведено наступне встановлення точності.
float m=2.1456;
cout << «m=» << setprecision(2) << m;
У результаті виконання попереднього коду на екран виведеться: m=2.14.
Для встановлення ширини поля при виводі можна використовувати маніпулятор потоку setw. Встановлення ширини поля впливає тільки на наступну операцію помістити в потік або узяти з потоку, потім ширина поля встановлюється на 0, тобто поля для представлення вихідних значень будуть такої ширини, яка необхідна для їх виводу.
int m=10;
сout << setw(10) << «m=» << m;
Маніпулятор setw(10) встановить ширину поля для виводу напису «m=», що дорівнює 10 символам, а для змінної m – ширину 0, але виведе значення змінної на ширину 2 символів, оскільки значення змінної m складається з двох цифр (m =10).
Якщо ширина поля, що задана за допомогою setw, більше, ніж ширина значення, що виводиться, то зайві позиції за замовчанням заповнюються пропусками. Маніпулятор setiosflags() використовується для заповнення зайвих позицій поля зліва або праворуч від значення, залежно від значення, заданого в дужках:
значення ios::left – заповнює зайві позиції після виведеного значення, тобто відбувається вирівнювання значення по лівому краю поля;
значення ios:: right – заповнює зайві позиції перед виведенням значення, тобто відбувається вирівнювання значення по правому краю поля.
За замовчанням встановлено вирівнювання виведеного значення по лівому краю поля. Символ, що заповнює зайві позиції, можна змінити за допомогою маніпулятора setfill.
сout << «m=» << setiosflags(ios:: right) << setw(8) << m;
Напис «m=» буде вирівняно по лівому краю поля (за замовчанням), а значення змінної m буде вирівняно по правому краю поля шириною 8 позицій.
У потокових класах разом з операціями << і >> визначені методи для неформатованого читання і запису в потік. Наведемо тільки декілька з них:
read(buf, num) – читає з потоку num символів (або всі символи до кінця файлу, якщо їх менше за num) в символьний масив buf і повертає посилання на поточний потік. Визначена у класі istreаm.
write(buf, num) – записує в потік num символів з масиву buf і повертає посилання на потік. Визначена у класі ostreаm.
Запитання для самоконтролю