Основи програмування на С ++ для початківців

Робота з локалізованими рядками

перше, що потрібно вміти робити з локалізованими рядками - це записувати символьні константи широких локалізованих символів і відрізняти їх від звичайних рядків char[]. Для цього рядок записується з попереднім їй кваліфікаторів L:

результатом буде:

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

У такій рядку поруч з рівним успіхом можуть стояти символи найрізноманітнішої природи: різних мов, спеціальні математичні символи, загальноприйняті в їхК.Є. позначення з грецького алфавіту (α, е, Я, Fr., р, L, F, Про ...), музичні ноти і ін. Як ви, очевидно, розумієте, точно також в складі рядків широких символів, з рівним успіхом, можуть зустрічатися і символи латинського алфавіту (основна таблиця ASCII), при цьому кожен такий символ теж буде займати 2 или 4 байт (в залежності від угод прийнятих в операційній системі), на відміну від звичного 1 байта.

Проробимо ряд операцій з російськомовними рядками, але записуючи їх (Бувай) в традиційній формі масивів char:

виконуємо:

Здавалося б, що (майже) все працює в точності як за підручником і навіщо нам якісь широкі локалізовані рядки? Але це оманлива ілюзія! Справа тут в тому, що деякі традиційні малі функції (strcat(), strcpy(), strdup(), strstr() та ін.) повертатимуть коректний результат. Це тому що вони виконують операції над байтами, байт за байтом, не вникаючи у внутрішню структуру копіюються символів.

Але інші операції (і помилковий результат strlen() на це вже наочно вказує) будуть працювати належним чином: strncpy(), strchr(), strsep(), strtok() та ін. И вони будуть створювати вам дуже несподівані результати, вельми складні для тлумачення. подивисявони як спрацює побайтовой реверс рядки, і як різниться його робота на англомовній та російськомовній рядку:

Чи спрацює це так, і це безперечно НЕ, що ви розраховували отримати:

Nа це ми закінчимо розгляд можливості подання російськомовних рядків традиційними масивами char[] і обробка їх традиційними малими функціями, і завершимо це розгляд висновком: работать з російськомовними рядками як масивом char можна только:

а). або коли ми використовуємо рядкові константи в незмінному вигляді, тільки як рядки для їх введення-виведення в незмінному вигляді;

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

У всіх решті випадків коректная робота з кирилицею можлива тільки як з масивами широких локалізованих символів wchar_t (з завершающім рядок широким нульовим символом L » 0′). Для роботи з таким поданням локалізованих рядків бібліотека C надає широкий набір малих функцій, повністю аналогічний традиційним рядковим функцій, але замість префікса str в їхніх іменах використовується префікс WCS: wcslen() замість strlen(), wcsncpy() замість strncpy() і т.д.

Подивимося як це працює на прикладі:

Такий ілюстрації цілком достатньо для того, щоб побачити прямі аналогії використання функцій роботи з символами wchar_t. той, хто має деякий досвід роботи з рядками char без зусиль перенесе його широкі рядки. Установка мовної локалі (виклик setlocale()) пристрою виведення (терміналу) - обов'язкова, тому що за замовчуванням програма C / C ++ встановлює локаль “C” (тадо склалося історично), яка допускає висновок тільки 128 символів молодшої половини 8-бітної таблиці ASCII.

У показаному написанні функція встановлює локаль, використовувану в операційній системі за замовчуванням - я припускаю, що ми експериментуємо в російськомовній встановленій системі. Новий стандарт мови (C99) вводить і новий формат для функцій форматування рядків (Printf(), Sprintf()) - %Ls, це форматування рядків wchar_t[].

ТТочно так само, як і з масивами char, які перейшли в C ++ з C, бібліотека C ++ вводить повну аналог контейнерного класу string, але що містить в своєму складі широкі локалізовані символи, і носить назву цей клас wstring:

Тут висновок рядка локалізованих символів (WS) повинен виводиться в потік виводу wcout (аналогічний за змістом cout, але відмінний від cout).

У показаному написанні: місце дії::глобальної( місце дії( “” ) ) - це установка локалі за замовчуванням в ООП манері C ++, аналогічно тому, як це було показано раніше в манері C.

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

залишити коментар

Ваша електронна адреса не буде опублікований. Обов'язкові поля позначені * *