Символи і рядки

До сих пір ми працювали тільки з числовими даними, як цілими, так і дійсними. Але дуже часто (якщо мова йде не про суто наукових розрахунках) доводиться оперувати з текстовою інформацією. У цьому листочку міститься основна інформація про принципи роботи з символами і текстами.

Символьний тип char

Будь-який текст складається із символів. Символ - це певний значок, зображення. Один і той же символ можна записати по-різному, наприклад, дві людини по-різному напишуть від руки букву "A", і навіть в комп'ютерному поданні одна і та ж буква буде виглядати по-різному, якщо її відображати різними шрифтами, при цьому це буде все одно один і той же символ. Вірно і інше: різні символи можуть бути записані однаково, наприклад, ось дві різні літери, одна - латинського алфавіту, інша - російського: "A" і "А". Незважаючи на те, що вони виглядають однаково, зручніше вважати їх різними символами.

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

Спочатку домовилися під кодування одного символу відвести один байт, тобто 8 біт інформації. Таким чином можна було закодувати 256 різних значень, тобто в запису тексту можна використовувати 256 різних символів. Цього достатньо, щоб відобразити всі символи латинського алфавіту, цифри, розділові знаки і деякі інші символи. Стандарт, який вказує, які числові коди відповідають яким основним символам, називається ASCII. У таблицю ASCII включені символи з кодами від 0 до 127, тобто ASCII - це семібітний код. Ось так виглядає таблиця ASCII:

При цьому символи з кодами, меншими 32 - це спеціальні символи, що управляють, які не відображаються на екрані. Наприклад, для того, щоб позначити кінець рядка в системі Linux використовується один символ з кодом 10, а в системі Windows - два поспіль символу з кодами 13 та 10, символи з кодами 48-57 відповідають зображенню арабських цифр (зверніть увагу, символ з кодом 0 - це зовсім не символ, що відображається на екрані, як "0"), символи з кодами 65-90 - великі літери літери латинського алфавіту, а якщо до їх кодами додати 32, то вийдуть малі літери латинського алфавіту. У проміжках між зазначеними діапазонами знаходяться розділові знаки, математичні операції і інші символи.

Ми будемо працювати тільки з символами ASCII, тому для представлення одного символу буде використовуватися тільки один байт.

У мові C ++ для зберігання однобайтового символу використовується тип даних char. Змінну типу char можна розглядати двояко: як ціле число, що займає 1 байт і здатне приймати значення від -128 до 127 (тип signed char. Є також Беззнаковая модифікація unsigned char. Приймаюча значення від 0 до 255) і як один символ тексту. Саме по собі визначення char може виявитися як знаковим, так і беззнаковим, в залежності від операційної системи і компілятора. Тому використовувати тип char не рекомендується, краще явно вказувати чи буде він знаковим (signed) або беззнаковим (unsigned).

Як і цілі числа, дані типу char можна додавати, віднімати, множити і навіть ділити. Але якщо операції множення і ділення, як правило, безглузді, то додавання і віднімання цілком осмислено. Наприклад, якщо до символу 'A' додати 1, то вийде символ 'B'. а якщо відняти 1, то вийде символ '@'. Тобто в наступному фрагменті коду на екран буде виведена літера B.

У цьому прикладі видно, що змінним типу char можна присвоювати значення, рівні ASCII кодами символів, якщо ці символи брати в лапки. Тобто запис 'A' буде відповідати символу A. або ASCII коду 65.

Також в цьому прикладі видно, що при виведенні на екран змінної типу char ми побачимо зображення цього символу. Як же дізнатися значення ASCII-коду символу? Його не потрібно дізнаватися, сам символ - це і є ASCII-код. А як його вивести на екран? Дуже просто - потрібно конвертувати першу одиницю величини типу char до значення типу int. Наприклад, ось так:

Ім'я типу, записане в дужках перед значенням, це і є оператор перетворення значення до зазначеного типу.

Аналогічно, при зчитуванні змінної типу char через потік cout. з потоку введення зчитується один символ, змінна отримує значення, рівне його ASCII-коду. Наприклад, якщо написати програму, що містить рядок

запустити її, ввести символ A (без жодних лапок!), то в змінну c буде записано значення 65 - ASCII-код символу A.

Змінним типу char можна і явно привласнювати числові значення. Наприклад, можна зробити так:

Ця програма виведе два рядки: "A 65" і "

126 ", тобто символи з ASCII-кодами 65 (A) і 126 (

) І самі ASCII-коди.

Організувати послідовне посимвольного зчитування всього вхідного потоку можна за допомогою циклу while.

У цьому прикладі програма буде посимвольний зчитувати вхідний потік (за замовчуванням - введення з клавіатури), поки не зустріне ознака кінця файлу. Для того, щоб повідомити програмі про завершення вхідного потоку при введенні з клавіатури необхідно натиснути клавіші Ctrl-d в системі Linux і Ctrl-z в системі Windows.

Ця програма при зчитуванні даних буде ігнорувати символи-роздільники: прогалини, символи нового рядка і табуляції. Якщо потрібно, щоб в змінну c зчитувалися все символи, в тому числі і роздільники, то необхідно для потоку введення cin встановити маніпулятор noskipws за допомогою інструкції:

Рядки в мові C ++

Текстовий рядок - це послідовність символів. Оскільки символи в рядку пронумеровані, то природним поданням для рядка був би масив символів. Так рядки і представлялися в мові C - рядком вважався масив символів, а для позначення кінця рядка використовувався символ з ASCII-кодом 0, що дозволяло зберігати рядки змінної довжини (тобто в масиві char [n] можна було зберігати рядки будь-якої довжини, що не перевищує n-1. Такий спосіб зберігання рядків породжував ряд незручностей: будь-який рядок була обмежена по довжині розміром масиву, а щоб обчислити довжину рядка необхідно було пройти по всій рядку до появи нульового символу, тобто визначення довжини рядка вимагає кількість операцій, пропорц іональное цієї довжині.

У мові C ++ для подання рядків існує більш досконалий тип даних string. в основі якого лежить такий же масив символів, що завершується нульовим символом, але містить ще ряд додаткових можливостей. Для роботи з рядками мови C ++ необхідно на початку програми підключити опис типу string. яке знаходиться в однойменному файлі:

Змінна для зберігання строкових даних оголошується так:

Присвоїти строкової змінної деякий константне значення можна так:

Із записом рядків в тексті програми в лапках ми вже зустрічалися, коли виводили текст в потік cout. Зверніть увагу - константи типу char записуються в одинарних лапках, а рядки - в подвійних лапках. Зокрема, 'A' - це символ, а "A" - це рядок, що складається з одного символу. Тому змінної типу char можна привласнити значення "A". оскільки вони мають несумісні типи даних.

По суті, змінна типу string є масивом символів і з кожним символом цього рядка можна працювати по-окремо, звертаючись до них за індексом, як до елементів масиву. наприклад:

Для визначення довжини рядка є метод size (). застосовуваний до рядка. Він повертає ціле число - кількість символів в рядку. Його можна використовувати так:

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

Основна операція над рядками - складання: наприклад, при додаванні рядків "Hello," і "world!" вийде рядок "Hello, world!". Така операція над рядками називається конкатенацией.

Ось приклад використання конкатенації рядків:

Інша операція - зміна розміру рядка. Для цього існує метод resize. який застосовується до рядка. У методу resize є дві форми запису: з одним і з двома параметрами. Якщо він викликається з одним параметром, то цей параметр задає нову довжину рядка. Наприклад, так:

Другий параметр методу resize задає символ, яким будуть заповнені символи в рядку, якщо розмір рядка збільшується в результаті зміни розміру. наприклад:

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

ввести текст 'Мама мила раму' (з будь-якою кількістю пробілів між словами), то в масив S1 буде записаний рядок "Мама". в S2 - "мила". в S3 - "раму".

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

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

В даному випадку якщо запустити цю програму і ввести рядок "Мама мила раму". то саме це значення і буде присвоєно рядку S. Вважати ж весь вхідний потік по рядках можна за допомогою наступного коду:

вправи

A: ASCII-код символу

Вважайте зі стандартного введення символ і виведіть його ASCII-код. Розв'яжіть цю задачу з використанням тільки однієї змінної типу char.

Програма отримує на вхід один символ з ASCII кодом від 33 до 126.

Схожі статті