Лабораторна робота № 7 потокові класи

Потокові класи в С++.

Бібліотека потокових класів С++ побудована на основі двох базових класів:iosтаstreambuf.

Клас streambuf забезпечує організацію та взаємозв'язок буферів введення-виведення, що розміщуються в пам'яті, з фізичними пристроями введення-виведення. Методи та дані класу streambuf програміст явно зазвичай не використовує. Цей клас потрібен іншим класам бібліотеки вводу-виводу. Він доступний і програмісту для створення нових класів на основі існуючих.

Клас ios містить засоби для форматованого введення-виводу та перевірки помилок.

istream – клас вхідних потоків;

ostream – клас вихідних потоків;

iostream – клас введення-виведення;

istrstream – клас вхідних рядкових потоків;

ifstream – клас вхідних файлових потоків тощо.

Поточні класи, їх методи та дані стають доступними у програмі, якщо до неї включений потрібний заголовний файл.

– для ios, ostream, istream.

– для strstream, istrstream, ostrstream

- для fstream, ifstream, ofstream

Базові потоки введення-виведення.

Для введення з потоку використовують об'єкти класу istream, для виведення в потік – об'єкти класу ostream.

У класі istream визначено такі функції:

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

Розділювач витягується з потоку, але в буфер не заноситься. Це основна функція для вилучення рядків із потоку. Прочитані символи завершуються нульовим символом.

Копіює дані з istream у streambuf, доки не виявить кінець файлу або символ-розділювач, який не витягується з istream. S нульовий символ не записується.

istream get (char& С);

Читає символ зistream у С. У разі помилки С набуває значення 0XFF.

Витягує з istream черговий символ. Після виявлення кінця файлу повертає EOF.

Повертає черговий символ із istream, не виймаючи його з istream.

Повертає кількість символів, прочитаних під час останньої операції неформатованого введення.

Якщо в області get об'єкта streambuf є вільний простір, то розміщується символ С.

Витягує символ із istream, доки не відбудеться наступне:

 функція не отримає count символів;

 не буде виявлено символ target;

 не буде досягнуто кінця файлу.

У класі ostream визначено такі функції:

Поміщає в ostream символ.

Записує в ostream вміст буфера. Символи копіюються доти, доки не виникне помилка або не буде скопійовано size символів. Буфер записується без форматування. Обробка нульових символів нічим не відрізняється від обробки інших. Дана функція здійснює передачу необроблених даних (бінарних чи текстових) в ostream.

Скидає буфер streambuf.

Для прямого доступу використовуються такі функції встановлення позиції читання – запису.

Встановлює покажчик потоку get (не плутати з функцією) зі зміщенням від початку потоку.

Вказується початкова точка переміщення.

Позитивне значення р переміщає покажчик get вперед (кінець потоку), негативне значення р – назад (до початку потоку).

Повертає поточне положення покажчика get.

Переміщає вказівник put в streambuf на позицію р від початку streambuf буфера.

Вказує точку відліку.

Повертає поточне положення вказівника put.

Крім цих функцій у класі istream перевантажений оператор >>, а в класі ostream> Лівим операндом є об'єкт класу istream (ostream), а правим – це, тип якого заданий у мові.

Щоб використовувати оператор > для всіх стандартних типів даних використовується відповідна кількість перевантажених функцій operator >. При виконанні операцій введення-виведення залежно від типу правого операнда викликається та чи інша перевантажена функція operator.

Підтримуються такі типи даних: цілі, речові, рядки (char*). Для виведення – void* (всі покажчики, відмінні від char*, автоматично переводяться до void*). Перевантаження операторів >> та >повертають посилання на той потоковий об'єкт, який вказаний зліва від знака операції. Таким чином, можна формувати "ланцюжки" операцій.

Під час введення-виведення можна форматувати дані.

Для використання операторів >> та > до стандартних потоків cout, cin, cerr, clog для даних базових типів призводить до використання "умовчуються" форматів зовнішнього уявлення значень, що пересилаються.

Формати представлення інформації та правила сприйняття даних при введенні можуть бути змінені програмістом за допомогою прапорів форматування. Ці прапори успадковано всіма потоками з базового класу ios. Прапори форматування реалізовані у вигляді окремих фіксованих бітів і зберігаються у protected компоненті класу long x_flags. Для доступу до них є відповідні громадські функції.

Крім прапорів форматування використовуються такі protected компонентні дані класу ios:

int x_width – мінімальна ширина поля виведення.

int x_precision – точність подання дійсних чисел (кількість цифр дробової частини) під час виведення;

int x_fill – символ-заповнювач під час виведення, пробіл – за замовчуванням.

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

Незважаючи на гнучкість та великі можливості управління форматами за допомогою компонентних функцій класу ios, їх застосування є досить громіздким. Простіший спосіб зміни параметрів та прапорів форматування забезпечують маніпулятори.

Маніпуляторами називаються спеціальні функції, що дозволяють модифікувати роботу потоку. Особливість маніпуляторів полягає в тому, що їх можна використовувати як правий операнд оператора >> або >(istream&(*_f)( istream&));

ostream& operator, у якому визначено вбудовані маніпулятори.

Визначення користувацьких маніпуляторів.

Порядок створення маніпулятора користувача з параметрами, наприклад для виведення, наступний:

1. Визначити клас (my_manip) із полями: параметри маніпулятора, покажчик на функцію типу

2. Визначити конструктор цього (my_manip) з ініціалізацією полів.

3. Визначити, у цьому класі дружню функцію – operator:

Кожен потік має пов'язані з ним стан. Стан потоку описуються в класі ios у вигляді перерахування enum.

goodbit, //немає помилки 0Х00

eofbit, //кінець файлу 0Х01

failbit // остання операція не виконалася 0Х02

badbit // Спроба використання неприпустимої операції 0Х04

hardfail //Фатальна помилка 0Х08

Прапори, що визначають результат останньої операції з об'єктом ios, містяться в змінному стані. Отримати значення цієї змінної можна з допомогою функції int rdstate().

Крім того, перевірити стан потоку можна такими функціями:

int bad(); 1, якщо badbit або hardfail

int eof(); 1, якщо eofbit

int fail(); 1, якщоfailbit, badbit або hardfail

int good(); 1, якщо goodbit

Якщо оператор >> використовується для нових типів даних, то при перевантаженні необхідно передбачити відповідні перевірки.

Потоки для роботи з файлами створюються як такі об'єкти:

ofstream - запис у файл;

ifstream – читання із файлу;

Для створення потоків є такі конструктори:

створює потік, не приєднуючи його до жодного файлу.

fstream(const char* name,int mode,int p=filebuf::openprot);

створює потік, приєднує його до файлу з ім'ям name, попередньо відкривши файл, встановлює йому режим mode і рівень захисту p. Якщо файл не існує, він створюється. Для mode=ios::out, якщо файл існує, його розмір буде зрізаний до нуля.

Прапори режиму визначені у класі ios і мають такі значення:

out  для запису

ate - індекс потоку поміщений у кінець файлу. Читання більше не допустиме, вивідні дані записуються на кінець файлу;

app  потік відкритий для додавання даних до кінця. Незалежно від seekp(), дані будуть записуватися в кінець;

trunc - усічення існуючого потоку до нуля;

nocreate - команда відкриття потоку буде завершена невдало, якщо файл не існує;

noreplace -команда відкриття потоку буде завершена невдало, якщо файл існує;

binary-потік відкривається для двійкового обміну.

Якщо під час створення потоку він не приєднано до файлу, то приєднати існуючий потік до файлу можна функцією

void open(const char* name,int mode,int p=filebuf::openprot);

скидає буфер потоку, від'єднує потік від файлу та закриває файл. Цю функцію необхідно явно викликати у разі зміни режиму роботи з потоком. Автоматично вонавикликається лише після завершення програми.

Таким чином, створити потік і зв'язати його з файлом можна трьома способами:

1. Створюється об'єкт filebuf

Об'єкт filebuf зв'язується з пристроєм (файлом)

Створюється потік і зв'язується з файломbuf

2. Створюється об'єкт fstream (ifstream, ofstream)

Відкривається файл, який зв'язується через filebuf з потоком

3. Створюється об'єкт fstream, одночасно відкривається файл, який зв'язується із потоком

Порядок виконання роботи.

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

2. Написати програму № 1 для створення об'єктів користувальницького класу (введення вихідної інформації з клавіатури з використанням перевантаженого оператора “>>) та збереження їх у потоці (файлі). Передбачити у програмі виведення повідомлення про кількість збережених об'єктів та довжину отриманого файлу в байтах.

3. Виконати тестування програми.

4. Реалізувати для виведення у потік свій маніпулятор із параметрами.

Калькулятор

Сервіс безкоштовної оцінки вартості роботи

  1. Заповніть заявку. Фахівці розрахують вартість вашої роботи
  2. Розрахунок вартості прийде на пошту та по СМС

Номер вашої заявки

Зараз на пошту прийде автоматичний лист-підтвердження з інформацією про заявку.