Помощничек
Главная | Обратная связь


Археология
Архитектура
Астрономия
Аудит
Биология
Ботаника
Бухгалтерский учёт
Войное дело
Генетика
География
Геология
Дизайн
Искусство
История
Кино
Кулинария
Культура
Литература
Математика
Медицина
Металлургия
Мифология
Музыка
Психология
Религия
Спорт
Строительство
Техника
Транспорт
Туризм
Усадьба
Физика
Фотография
Химия
Экология
Электричество
Электроника
Энергетика

Введення, орієнтоване на рядки за допомогою get()



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

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

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

Інший спосіб застосування get() полягає в конкатенації, або з'єднанні, двох викликів функцій-членів класу:

Таку можливість забезпечує те, що cin.get(name, ArSize) повертає об'єкт cin, який потім використовується як об'єкт, що викликає функцію get(). Аналогічно оператор читає два наступних один за одним рядки в масиви name1 і name2, що еквівалентно двом окремим викликам cin.getline():

В лістингу 5 використовується конкатенація:

Приклад запуску програми:

Зверніть увагу на те, що C++ допускає існування безлічі версій функції з різними списками аргументів.

Якщо ви використовуєте, скажімо, cin.get(name, ArSize), то компілятор визначає, що викликається форма, яка поміщає рядок в масив, і підставляє відповідну функцію-член. Якщо ж замість цього ви застосовуєте cin.get(), то компілятор бачить, що вам потрібна форма, яка читає один символ. Такий засіб називається перевантаженням функцій.

Навіщо взагалі може знадобитися викликати get() замість getline()? По-перше, старі реалізації можуть не містити getline(). По-друге, get() дозволяє виявляти більшу обережність. Припустимо, наприклад, що ви скористалися get(), щоб прочитати рядок в масив. Як ви визначите, був прочитаний повний рядок або ж читання перервалося у зв'язку із заповненням масиву? Для цього потрібно подивитися на наступний у черзі символ. Якщо це символ нового рядка, значить, був прочитаний весь рядок. В іншому випадку рядок був прочитаний не повністю і ще є що читати. Коротше кажучи, getline() трохи простіше в застосуванні, але get() спрощує перевірку помилок.

Порожні рядки та інші проблеми

Що відбувається після того, як функції getline() і get() прочитали порожній рядок? Спочатку передбачалося, що наступний оператор введення повинен отримати вказівку, де завершив роботу попередній виклик getline() або get(). Однак сучасна практика полягає в тому, що після того, як функція get() (але не getline()) прочитає порожній рядок, вона встановлює прапорець, який називається failbit. Вплив цього прапорця полягає в тому, що подальше введення блокується, але його можна відновити наступною командою:

Інша потенційна проблема пов'язана з тим, що вхідні рядки можуть бути довшими, ніж виділений для них простір. Якщо вхідні рядки довші, ніж вказана кількість символів, то і getline(), і get() залишають надлишкові символи у вхідній черзі. Однак getline() додатково встановлює failbit і відключає подальше введення.

 




Поиск по сайту:

©2015-2020 studopedya.ru Все права принадлежат авторам размещенных материалов.