
- •Лекція 1
- •Зауваження до програми
- •Правила ініціалізації масивів
- •Лекція 2
- •Конкатенація рядкових літералів
- •Використання рядків у масивах
- •Зауваження до програми
- •Ризики, пов'язані з введенням рядків
- •Читання введення по рядках
- •Введення, орієнтоване на рядки за допомогою getline()
- •Введення, орієнтоване на рядки за допомогою get()
- •Змішування рядкового та числового вводу
- •Клас string
- •Лекція 3
- •Використання структур в програмах
- •Зауваження до програми
- •Чи може структура містити член типу string?
- •Інші властивості структур
- •Масиви структур
- •Лекція 4
- •Перерахування
- •Встановлення значень нумераторам
- •Діапазони значень нумераторів
- •Лекція 5
- •Оголошення та ініціалізація вказівників
- •Небезпека пов’язана з вказівниками
Конкатенація рядкових літералів
Іноді рядки можуть виявитися занадто великими, щоб зручно розміститися в одному рядку коду. C++ дозволяє виконувати конкатенацію строкових літералів - тобто комбінувати два рядки з подвійними лапками в одну. Насправді будь-які дві рядкові константи, розділені тільки пробільним символом (пробілами, символами табуляції і символами нового рядка), автоматично об'єднуються в одну. Таким чином, наступні три оператора виведення еквівалентні:
Зверніть увагу, що такі об'єднання не додають ніяких прогалин до рядків, що об'єднуються. Перший символ другого рядка негайно слідує за останнім символом першого, не рахуючи «\0» в першому рядку. Символ «\0» з першого рядка замінюється першим символом другого рядка.
Використання рядків у масивах
Два найбільш поширених методи вставки рядки в масив полягають в ініціалізації масиву рядковою константою і читанням з клавіатурного або файлового введення в масив. У лістингу 2 ці підходи демонструються за рахунок ініціалізації одного масиву рядком у подвійних лапках і використання cin для вставки рядка, що вводиться в інший масив. У програмі також застосовується стандартна бібліотечна функція stlen() для отримання довжини рядка. Стандартний заголовковий файл cstring (або string.h в старіших реалізаціях) надає оголошення для цієї та багатьох інших функцій, що працюють з рядками.
Лістинг 2. string.cpp
Нижче показано приклад виконання програми з лістингу 2:
Зауваження до програми
Чому вчить код в лістингу 2? Спершу, зверніть увагу, що операція sizeof повертає розмір всього масиву - 15 байт, але функція strlen() повертає розмір рядка, що зберігається в масиві, а не розмір самого масиву. До того ж strlen() підраховує тільки видимі символи, без нульового символу-обмежувача. Тобто ця функція повертає як довжини Basicman значення 8, а не 9. Якщо cosmic - рядок, то мінімальний розмір масиву для розміщення цього рядка обчислюється як strlen(cosmic)+1.
Оскільки name1 і name2 - масиви, для доступу до окремих символів в цих масивах можна використовувати індекси. Наприклад, у програмі для пошуку першого символу масиву name1 застосовується name1[0]. Крім того, програма присвоює елементу name2[3] нульовий символ. Це завершує рядок після трьох символів, хоча в масиві залишаються ще символи (мал. 3).
Мал. 3. Скорочення рядка за допомогою \0
Зверніть увагу, що в програмі з лістингу 2 для вказівки розміру масива використовується символьна константа. Часто розмір масиву потрібно вказувати в декількох операторах програми. Застосування символьних констант для представлення розміру масиву спрощує внесення змін, пов'язаних з довжиною масива; в таких випадках змінити розмір буде потрібно тільки в одному місці - там, де визначена символьна константа.
Ризики, пов'язані з введенням рядків
Програма string.срр має недолік, прихований за часто використовуваною в літературі технікою ретельного вибору прикладів введення. У лістингу 3 продемонстровано той факт, що введення рядків може виявитися непростим.
Лістинг 3. insrtl.cpp
Призначення програми з лістингу 3 просте: прочитати ім'я користувача і назву його улюбленого десерту, введені з клавіатури, і потім відобразити цю інформацію.
Нижче наведено приклад запуску:
Ми навіть не отримали можливості відповісти на питання про десерт! Програма показала питання і потім негайно перейшла до відображення заключного рядка.
Проблема пов'язана з тим, як cin визначає, коли введення рядка завершено. Ви не можете ввести нульовий символ з клавіатури, тому cin потрібно щось інше для знаходження кінця рядка. Підхід, прийнятий в cin, полягає у використанні пробільних символів для розділення рядків - пробілів, знаків табуляції і символів нового рядка. Це означає, що cin читає тільки одне слово, коли отримує вввведення для символьного масиву. Після читання слова cin автоматично додає обмежуючий нульовий символ при вставці рядка в масив.
Практичний результат цього прикладу полягає в тому, що cin читає слово Alistair як повний перший рядок і поміщає його в масив name. При цьому друге слово, Dreeb, залишається у вхідній черзі. Коли cin шукає введення, що відповідає на питання про десерт, він знаходить там Dreeb. Потім cin захоплює слово Dreeb і поміщає його в масив dessert (мал. 4).
Ще одна проблема, яка не була виявлена в прикладі запуску, полягає в тому, що запроваджуваний рядок, у свою чергу, може бути довше, ніж цільовиї масив. При такому використанні cin, як це зроблено в прикладі, немає ніякого захисту від вставки 30-символьного рядка в 20-символьний масив.
Мал. 4. Введення рядка з точки зору cin