Лекція 9: Символьні масиви (C-style strings) та функції роботи з ними
У C++ є два способи працювати з текстом:
std::string— сучасний, зручний об'єкт (ми вже трохи торкалися його раніше).- C-style strings (С-рядки) — прості масиви символів (
char). Саме так працювали з текстом у старій мові C.
Сьогодні ми заглибимося в "підкапотну" частину — масиви char.
1. Що таке рядок у пам'яті?
Для комп'ютера текст — це просто послідовність символів, що лежать один за одним у пам'яті.
Питання: як комп'ютер знає, де закінчується слово "Hello" і починається інший "сміття" з пам'яті?
Відповідь: Null-terminator (\0). Кожен C-style рядок обов'язково закінчується спеціальним символом, код якого дорівнює 0. У коді це записується як '\0'.
Приклад: Слово "Hi" у пам'яті займає 3 байти, а не 2: ['H'] ['i'] ['\0'].
2. Оголошення та ініціалізація
Оскільки це масив, синтаксис вам знайомий. Але важливо пам'ятати про місце для \0!
char word[6] = "Hello"; // 5 літер + 1 нуль-термінатор = 6 комірок
Якщо написати char word[5] = "Hello";, це буде помилка — не вистачить місця для термінатора!
Краще дозволити компілятору самому порахувати розмір:
char greeting[] = "Hello World"; // Розмір автоматично буде 12
3. Проблема введення (cin)
Недолік звичайного cin: він читає текст лише до першого пробілу.
#include <iostream>
using namespace std;
int main() {
char name[50];
cout << "Введіть ім'я та прізвище: ";
cin >> name; // Якщо ввести "Taras Shevchenko"
cout << name; // Виведе тільки "Taras"
return 0;
}
Рішення: Функція cin.getline(). Вона приймає два параметри: куди записати (масив символів) та максимальний розмір.
#include <iostream>
using namespace std;
int main() {
char fullName[100];
cout << "Введіть повне ім'я: ";
cin.getline(fullName, 100); // Прочитає весь рядок із пробілами
cout << "Привіт, " << fullName << endl;
return 0;
}
4. Бібліотека <cstring> (або <string.h>)
Масиви char — це не об'єкти, тому прямі операції неможливі:
str1 = str2— не працює!str1 == str2— не працює!str3 = str1 + str2— не працює!
Для цих операцій існують спеціальні функції. Підключіть бібліотеку: #include <cstring>
strlen(str) — Довжина рядка
Повертає довжину рядка (кількість символів без \0).
#include <iostream>
#include <cstring>
using namespace std;
int main() {
char msg[] = "Hi";
cout << strlen(msg); // Виведе 2
return 0;
}
strcpy(dest, source) — Копіювання рядка
Копіює вміст одного рядка в інший.
#include <iostream>
#include <cstring>
using namespace std;
int main() {
char original[] = "Apple";
char copy[20];
strcpy(copy, original); // copy тепер "Apple"
// Увага! у 'copy' має бути достатньо місця!
return 0;
}
strcat(dest, source) — Конкатенація (склеювання)
Додає (приклеює) другий рядок в кінець першого.
#include <iostream>
#include <cstring>
using namespace std;
int main() {
char text[50] = "Hello, ";
char name[] = "User";
strcat(text, name); // text стає "Hello, User"
return 0;
}
strcmp(str1, str2) — Порівняння рядків
Порівнює два рядки по коду символів (алфавітний порядок).
- Повертає
0, якщо рядки однакові. - Повертає
< 0, якщо перший рядок йде раніше в алфавіті. - Повертає
> 0, якщо перший рядок йде пізніше.
#include <iostream>
#include <cstring>
using namespace std;
int main() {
char password[20];
cin >> password;
if (strcmp(password, "secret123") == 0) {
cout << "Пароль вірний!";
}
return 0;
}
5. Приклад використання функцій
#include <iostream>
#include <cstring> // Обов'язково для strlen, strcpy, strcat, strcmp
using namespace std;
int main() {
char str1[50] = "Super";
char str2[] = "Mario";
// 1. Об'єднання
strcat(str1, " "); // Додали пробіл: "Super "
strcat(str1, str2); // Додали Mario: "Super Mario"
cout << "Результат: " << str1 << endl;
cout << "Довжина: " << strlen(str1) << endl; // 11 символів
// 2. Порівняння
char login[20];
cout << "Введіть логін: ";
cin >> login;
if (strcmp(login, "admin") == 0) {
cout << "Вхід дозволено!" << endl;
} else {
cout << "Звичайний користувач." << endl;
}
return 0;
}
Практичні завдання до Лекції 9
Виконайте ці завдання в своєму середовищі розробки.
Завдання 1: Власний strlen
Напишіть програму, яка просить користувача ввести слово. Не використовуючи функцію strlen, порахуйте кількість символів у цьому слові.
Підказка: Використовуйте цикл while або for. Перебирайте символи str[i], доки не зустрінете нуль-термінатор '\0'.
Завдання 2: Детектор слів
Користувач вводить два слова. Програма має визначити:
- Яке слово довше.
- Чи однакові ці слова (ідентичні). Використовуйте функції з бібліотеки
<cstring>.
Завдання 3: Заміна символів (Цензура)
Користувач вводить речення (використовуйте cin.getline). Програма має пройтися по всьому масиву символів. Якщо вона знаходить літеру 'а' (англійську), вона замінює її на '@'. Якщо знаходить 'о', замінює на '0' (нуль). Виведіть оброблене речення.
Приклад: "Hello world and all" → "Hell0 w0rld @nd @ll"