Сайт вчителя інформатики та ікт - рядки в c і символьні масиви

Рядки в C ++ і символьні масиви

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

Текст в лапках і є строкова константа. Лапки використовуються для визначення початку і кінця строкової константи і її частиною є.

Отже про перший: в C ++ для зберігання рядків використовують символьні масиви. Це такі ж масиви, як ми з вами вже розглядали в статті про масивах в С ++, але зберігають вони не числові дані, а символьні. Можна уявити символи такого масиву розташованими послідовно в сусідніх комірках пам'яті - в кожному осередку зберігається один символ і займає один байт. Один байт тому, що кожен елемент символьного масиву має тип char. Останнім символом кожної такого рядка є символ \ 0 (нульовий символ). наприклад:


Сам текст, включаючи пробіл, складається з 11-ти символів. Якби в останній комірці перебувала наприклад. (Точка), а не нульовий символ \ 0 - для компілятора це вже не рядок. І працювати з таким набором символів треба було б, як зі звичайним масивом - записувати дані в кожну клітинку окремо і виводити на екран посимвольний (за допомогою циклу):
#include
using namespace std;

int main ()
setlocale (LC_ALL, "rus");

for (int i = 0; i <12; i++)
cout <>
cout <


На щастя в C ++ є куди більш зручний спосіб ініціалізації і звернення до символьних масивів - один рядок. Для цього останнім символом такого масиву обов'язково повинен бути нульовий символ \ 0. Саме він робить набір символів рядком, працювати з якою, набагато легше, ніж з масивом символів.

Оголошується рядок таким чином - створюємо масив типу char, розмір в квадратних дужках вказувати не обов'язково (його підрахує компілятор), оператор = і в подвійних лапках пишемо необхідний текст. Тобто инициализируем масив строкової константою:
#include
using namespace std;

int main ()
setlocale (LC_ALL, "rus");

char str [] = "Жив-був пес"; // '\ 0' присутній неявно

cout <

Прописувати нульовий символ не треба. Він присутній неявно і додається в кожну таку строкову константу автоматично. Таким чином, при тому що ми бачимо 11 символів в рядку, розмір масиву буде 12, так як \ 0 теж символ і займає один байт пам'яті. Займе він останній осередок цього символьного масиву. Як бачите, для виведення рядка на екран, досить звернутися до неї по імені: cout <

Хочу звернути вашу увагу на відмінність символьної константи (в одинарних лапках - 'f'. '@') Від строкової константи (в подвійних лапках "f". "@"). Для першої, компілятором C ++ виділяється один байт для зберігання в пам'яті. Для символу записаного в подвійних лапках, буде виділено два байта пам'яті - для самого символу і для нульового (додається компілятором).

Що якщо рядок повинен буде ввести користувач за допомогою клавіатури? В цьому випадку необхідно оголосити масив типу char із зазначенням його розміру достатнього для зберігання символів, що вводять, включаючи \ 0. Не забувайте про це нульовому символі. Якщо вам треба зберігати 3 символу в масиві, його розмір повинен бути на одиницю більше - тобто 4.

using namespace std;


Використовуючи порожні лапки при ініціалізації, ми присвоюємо кожному елементу масиву значення \ 0. Таким чином рядок буде очищена від «сміття» інших програм. Навіть якщо користувач введе назву містить меншу кількість символів, наступний за назвою буде символ \ 0. Це дозволить уникнути небажаних помилок. У пам'яті цей рядок буде виглядати так:


До речі, якщо допустимо перезаписати 11-ю осередок цього масиву - str [11] = '\ 0';


і відобразити масив на екрані, то побачимо тільки purecodecpp не дивлячись на те, що в осередках 12, 13, 14 залишилися зберігатися символи. Нульовий символ зіграє свою головну роль при виведенні на екран і все, що знаходиться за ним не буде показано.

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

#include
using namespace std;

int main ()
setlocale (LC_ALL, "rus");

char quote [128] = "";

cout <<"Ваша любимая цитата из мультфильма "Винни Пух": ";
cin >> quote;
cout <


Чи не морочитися поки над тим, що введення через cin необхідно виробляти латиницею. Про те як коректно ввести кирилицю буде розказано в окремій статті. Тут ви бачите, що цитату ми ввели, але при виведенні на екран, бачимо тільки перше слово. Це пов'язано з тим, що ми не можемо ввести нульовий символ з клавіатури, а cin сприймає пробіл, символ нового рядка і табуляцію, як кінець рядка. Тобто в нашому випадку cin прочитав тільки перше слово, кому і автоматично додав знак кінця рядка. Решта введені дані помістив до вхідної черги.

Вирішується ця проблема просто. У C ++ є функції get () і getline (). які ми можемо використовувати разом з cin. Вони схожі, але частіше використовується getline (). У цій статті ми не будемо розглядати їх відміну. Допишемо в нашу програму введення з getline ():
#include
using namespace std;

int main ()
setlocale (LC_ALL, "rus");

char quote [128] = "";

cout <<"Ваша любимая цитата из мультфильма "Винни Пух": \n";
cin.getline (quote, 128); // передаємо в функцію ім'я масиву і його розмір
cout <


Ви бачите, що в дужках ми вказали для функції два аргументи - в який масив вважати символи (ім'я масиву) і розмір цього масиву - рядок 11. Результат нам підходить - все відобразилося правильно. cin.getline () зчитує в масив всю рядок з пробілами і табуляції, поки не відбудеться натискання Enter або поки не буде перевищено розмір масиву. Символ нового рядка в масиві не збережеться, а заміниться на нульовий символ.