✨ C++: Кодування Символів

1. Кодування Символів та Кодові Таблиці

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

* **Одномірне кодування (Один байт):** * char — стандартний тип символів у C++, зазвичай займає **1 байт** (8 біт). Може зберігати 256 різних значень (від 0 до 255). * Приклади кодових таблиць: **ASCII** (7-бітне, для латинських літер, цифр, знаків пунктуації), **ISO-8859** (розширення ASCII), **Windows-1251** (для кирилиці). * **Багатобайтове кодування (Два або більше байтів):** * Використовується для представлення символів з великих наборів, як-от Юнікод (Unicode), що містить символи більшості писемностей світу. * Приклади: **UTF-8**, **UTF-16**, **UTF-32**.

Усі літери та інші символи, які використовуються для друку, кодуються двійковими числами.

Існують:

Коди всіх символів знаходяться в спеціальних таблицях і збігаються з їх порядковими номерами в цих таблицях.

Однобайтове кодування

В однобайтовому кодуванні (системі ASCII) закріплені дві таблиці кодування: базова (з кодами від 0 до 127) та розширена (з кодами від 128 до 255).

Базова таблиця (таблиця ASCII) однакова для всіх кодувань. У всіх задачах, які ми будемо вирішувати в цьому розділі, ми будемо використовувати лише символи з тієї таблиці.

Таблиця ASCII

Код Символ Код Символ Код Символ Код Символ
032 64@96-
1○33!65A97a
2●34"66B98b
3▼35#67C99c
4♦36$68D100d
5♣37%69E101e
6♦38&70F102f
7•39'71G103g
8■40(72H104h
941)73I105i
10✅42*74J106j
11✅43+75K107k
12○44,76L108l
13✅45-77M109m
14♫46.78N110n
15☆47/79O111o
16►48080P112p
17✅49181Q113q
18↑50282R114r
19!!51383S115s
2052484T116t
21§53585U117u
22—54686V118v
23↑55787W119w
24↑56888X120x
25↓57989Y121y
26›58:90Z122z
27<59;91[123{
28⊥60<92\124|
29< >61=93]125}
30▲62>94^126~
31▼63?95_127◇

З цієї таблиці потрібно пам'ятати тільки те, що:

Для того, щоб використовувати символи кирилиці, потрібно розглянути багато додаткової інформації (інший тип даних, інший ввід даних і т.і.)

Розширена таблиця

У розширеній таблиці розташовані національні системи кодування (символи кирилиці). Відсутність єдиного стандарту у цій галузі призвела до множинності одночасно діючих кодувань.

При програмуванні на мові С++ кодування символів може відрізнятися залежно від операційної системи та налаштувань компілятора.

Двобайтове кодування

В C++ можна налаштувати і двобайтове кодування. Це так звані широкі символи (UTF-8).

2. Двобайтове Кодування та Широкі Символи (wchar_t)

Для роботи з великими наборами символів, особливо в Windows-орієнтованих додатках (UTF-16), використовується тип **широких символів**.

2.1. Тип wchar_t

Тип wchar_t (від **w**ide **char**acter) — це тип, призначений для зберігання одного широкого символу. Його розмір визначається реалізацією компілятора, але часто це **2 або 4 байти** (наприклад, 2 байти для UTF-16 у Windows).

В C++11 з'явилися також більш специфічні типи:

---

3. Опис та Ініціалізація Змінних і Констант

Для ініціалізації широких символів використовується префікс **L** перед символом або рядком.

#include <iostream>
#include <clocale> // Для встановлення локалі

int main() {
    // Встановлення локалі для коректного виведення широких символів
    std::setlocale(LC_ALL, "uk_UA.UTF-8"); 
    
    // Звичайний символ (1 байт)
    char c1 = 'A';
    char c2 = 'Я'; // Може бути багатобайтовим або некоректним залежно від кодування вихідного файлу

    // Широкий символ (зазвичай 2 або 4 байти)
    wchar_t wc1 = L'A';
    wchar_t wc2 = L'€'; // Символ євро
    const wchar_t WC_CONST = L'🚀'; // Широка константа

    // Широкий рядок
    const wchar_t* ws = L"Привіт, Світ!";

    std::wcout << L"Широкий символ: " << wc2 << L"\n";
    std::wcout << L"Широкий рядок: " << ws << L"\n";
    std::wcout << L"Розмір wchar_t: " << sizeof(wchar_t) << L" байтів\n";

    return 0;
}
        
---

4. Отримання Коду Символу та Символу за Кодом

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

#include <iostream>
#include <clocale>

int main() {
    std::setlocale(LC_ALL, "uk_UA.UTF-8");
    
    // Отримання коду символу
    char my_char = 'A';
    wchar_t my_wchar = L'Ж'; // Символ "Ж"

    int char_code = (int)my_char;
    int wchar_code = (int)my_wchar;

    std::cout << "Код 'A': " << char_code << "\n"; // Напр., 65
    std::wcout << L"Код 'Ж': " << wchar_code << L"\n"; // Напр., 1046 (в Unicode)

    // Отримання символу за кодом
    int code_for_B = 66;
    int code_for_I = 1048; // Код Unicode для 'И'

    char char_from_code = (char)code_for_B;
    wchar_t wchar_from_code = (wchar_t)code_for_I;

    std::cout << "Символ за кодом 66: " << char_from_code << "\n"; // B
    std::wcout << L"Символ за кодом 1048: " << wchar_from_code << L"\n"; // И

    return 0;
}
        
---

5. Порівняння та Ввід/Вивід Символів

5.1. Порівняння

Символи (як char, так і wchar_t) можна порівнювати безпосередньо за допомогою звичайних операторів порівняння (==, !=, >, <), оскільки вони порівнюються за своїми числовими кодами.

char c1 = 'a';
char c2 = 'b';
bool is_greater = c2 > c1; // true, оскільки код 'b' > коду 'a'
        

5.2. Ввід/Вивід

---

6. Деякі Функції для Роботи з Символами

Стандартна бібліотека C++ пропонує набори функцій для маніпулювання символами:

Заголовок Функція (char) Широка Функція (wchar_t) Призначення
<cctype> isalnum() iswalnum() Перевіряє, чи є символ літерою або цифрою.
<cctype> islower() iswlower() Перевіряє, чи є символ малою літерою.
<cctype> isupper() iswupper() Перевіряє, чи є символ великою літерою.
<cctype> tolower() towlower() Перетворює символ у нижній регістр.
<cctype> toupper() towupper() Перетворює символ у верхній регістр.
#include <iostream>
#include <cctype>
#include <cwctype> // Для широких символів

int main() {
    char c = 'h';
    wchar_t wc = L'П';
    
    std::cout << "toupper('h'): " << (char)toupper(c) << "\n"; // H
    
    // towupper повертає wint_t, але використовується як wchar_t
    std::wcout << L"towlower('П'): " << (wchar_t)towlower(wc) << L"\n"; // п

    return 0;
}
        
---

🧠 Тест на Знання: Кодування Символів у C++

1. Скільки байтів зазвичай займає тип char?




2. Який префікс використовується для ініціалізації широкого рядка (const wchar_t*)?




3. Який потік використовується для виведення широких символів (wchar_t)?




4. Для чого призначена функція iswupper()?




5. Яке кодування часто використовується для широких символів у Windows (тип wchar_t 2 байти)?




6. Яким чином можна отримати числовий код символу 'Z'?




7. Який заголовок містить широкі функції типу iswlower()?




8. Який тип гарантовано має розмір 32 біти для зберігання символів UTF-32 (починаючи з C++11)?




9. Яка кодова таблиця є 7-бітною і містить латинські літери?




10. Чи можна порівнювати два символи wchar_t за допомогою оператора >?




11. Що необхідно зробити для коректного виведення широких символів на консоль (окрім використання std::wcout)?




12. Яке кодування є багатобайтовим, але може використовувати лише 1 байт для символів ASCII?