Урок №216. Функціонал класу istream

  Юрій  | 

  Оновл. 9 Жов 2021  | 

 143

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

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

Оператор вилучення

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

Що відбудеться, якщо користувач введе 20 символів? Правильно, переповнення. Одним із способів вирішення цієї проблеми є використання маніпуляторів. Маніпулятор — це об’єкт, який застосовується для зміни потоку даних з використанням операторів вилучення (>>) або вставки (<<).

Ми вже працювали з одним з маніпуляторів — endl, який одночасно виводить символ нового рядка і видаляє поточні дані з буфера. Мова C++ надає ще один маніпулятор — setw() (з заголовку iomanip), який використовується для обмеження кількості символів, які зчитуються з потоку. Для використання setw() вам потрібно просто передати в якості параметра максимальну кількість символів для вилучення і вставити виклик цього маніпулятора наступним чином:

Ця програма тепер прочитає тільки перші 11 символів з вхідного потоку (+ один символ для нуль-термінатора). Всі інші символи залишаться в потоці до наступного вилучення.

Вилучення і пробіли

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

Якщо користувач введе наступне:

Hello! My name is Anton

То оператор вилучення пропустить всі пробіли і символи нового рядка. Отже, результат виконання програми:

Hello!MynameisAnton

Часто користувацький ввід все ж потрібен з усіма його пробілами. Для цього клас istream надає безліч функцій. Однією з найбільш корисних є функція get(), яка вилучає символ з вхідного потоку. Ось вищенаведена програма, але вже з використанням функції get():

Тепер, якщо ми введемо наступне:

Hello! My name is Anton

То отримаємо:

Hello! My name is Anton

Функція get() також має рядкову версію, в якій можна вказати максимальну кількість символів для вилучення. Наприклад:

Якщо ми введемо наступне:

Hello! My name is Anton

То отримаємо:

Hello! My n

Зверніть увагу, програма зчитує тільки перші 11 символів (+ нуль-термінатор). Решта символів залишаються у вхідному потоці.

Один важливий нюанс: функція get() НЕ зчитує символ нового рядка! Наприклад:

Якщо користувач введе наступне:

Hello!

То отримає:

Hello!

І програма відразу ж завершить своє виконання! Чому так? Чому не спрацює другий ввід даних? Справа в тому, що перший get() зчитує символи до символу нового рядка, а потім зупиняється. Другий get() бачить, що у вхідному потоці все ще є дані і намагається їх отримати. Але перший символ, на який він натикається — символ нового рядка, тому відбувається другий «Стоп!».

Для вирішення даної проблеми клас istream надає функцію getline(), яка працює точно так само, як і функція get(), але при цьому може зчитувати символи нового рядка:

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

Якщо вам потрібно дізнатися кількість символів, вилучених останнім getline(), використовуйте функцію gcount():

Результат:

Hello! My name is Anton
24 characters were read

Спеціальна версія функції getline() для std::string

Є спеціальна версія функції getline(), яка знаходиться поза класом istream і використовується для зчитування змінних типу std::string. Вона не є членом ні ostream, ні istream, а підключається заголовком string. Наприклад:

Ще декілька корисних функцій класу istream

Є ще кілька корисних функцій класу istream, які ви можете використовувати:

   функція ignore() — ігнорує перший символ з потоку;

   функція ignore(int nCount) — ігнорує перші nCount (кількість) символів з потоку;

   функція peek() — зчитує символ з потоку, при цьому не видаляючи його з потоку;

   функція unget() — повертає останній зчитаний символ назад в потік, щоб його можна було вилучити в наступний раз;

   функція putback(char ch) — поміщає обраний вами символ назад в потік, щоб його можна було вилучити наступного разу.

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

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

1 Зірка2 Зірки3 Зірки4 Зірки5 Зірок (1 оцінок, середня: 5,00 з 5)
Loading...

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

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