Студопедия КАТЕГОРИИ: АвтоАвтоматизацияАрхитектураАстрономияАудитБиологияБухгалтерияВоенное делоГенетикаГеографияГеологияГосударствоДомЖурналистика и СМИИзобретательствоИностранные языкиИнформатикаИскусствоИсторияКомпьютерыКулинарияКультураЛексикологияЛитератураЛогикаМаркетингМатематикаМашиностроениеМедицинаМенеджментМеталлы и СваркаМеханикаМузыкаНаселениеОбразованиеОхрана безопасности жизниОхрана ТрудаПедагогикаПолитикаПравоПриборостроениеПрограммированиеПроизводствоПромышленностьПсихологияРадиоРегилияСвязьСоциологияСпортСтандартизацияСтроительствоТехнологииТорговляТуризмФизикаФизиологияФилософияФинансыХимияХозяйствоЦеннообразованиеЧерчениеЭкологияЭконометрикаЭкономикаЭлектроникаЮриспунденкция |
Зміна порядку символів рядка На зворотнійСтр 1 из 2Следующая ⇒
ОПЕРАЦІЇ З РЯДКАМИ МАСИВИ СИМВОЛІВ в C++ У стандарт C++ включена підтримка декількох наборів символів. Традиційний 8 бітовий набір символів називається "вузькими" символами. Крім того, включена підтримка 16 бітових символів, які називаються "широкими". Для кожного із цих наборів символів у бібліотеці є своя сукупність функцій. Як і в С , для символьних рядків в C++ не існує спеціального строкового типу. Замість цього рядка в C++ представляються як масиви елементів типу char, що закінчуються термінатором рядка – символом з нульовим значенням ('\0'). Рядки, що закінчуються нуль-термінатором, часто називають Ascii Рядками. Символьні рядки складаються з набору символьних констант, взятих в подвійні лапки: "Це рядок символів..." У таблиці наведений набір констант, що застосовуються в C++ у якості символів.
При оголошенні строкового масиву необхідно брати до уваги наявність термінатора наприкінці рядка, відводячи тим самим під рядок на один байт більше: char buffer [10] ; // оголошення рядка розміром 10 символів, включаючи термінатор. // Реальний розмір рядка: 9 символів + термінатор. Строковий масив може при оголошенні ініціалізуватись початковим значенням. При цьому компілятор автоматично обчислює розмір майбутнього рядка й додає в кінець нуль-термінатор: char Wednesday [ ] = "Середовище"; // оголошення й ініціалізація рядка char Wednesday [ ] = { 'С', 'р', 'е', 'д', 'а', '\0' } ; // що рівносильне У якості оператора введення при роботі з рядками замість оператора запису в потік >> краще використовувати функцію getline, тому що потоковий оператор уведення ігнорує проміжки, що вводяться, а крім того, може продовжити введення елементів за межами масиву, якщо під рядок приділяється менше місця, чим уводиться символів. Синтаксис функції getline має вигляд: istream&getline ( char* pch, int ncount, char delim = '\n' ) ; Функція getline приймає два обов'язкові параметри: перший аргумент pch вказує на рядок, у який здійснюється введення, а другий параметр ncount – число символів, що підлягають уведенню. Третій необов'язковий параметр delim – символ, який буде перетворений у нуль-термінатор. За замовчуванням це символ кінця рядка '\n'. Розглянемо приклад оголошення символьних рядків і використання функції введення getline. char S [6] ;// оголошення й ініціалізація рядка довжиною в 5 символів cout<<"Input string: " ;// вивід на екран запрошення cin.getline ( S, 6, ’.’ ) ;// увед рядка довж.,=5символів, увед рядка завер крапкою cout<<"You input string: "<<S<<'\n' ; // вивід рядка Оголошений на початку програми рядок S може прийняти тільки п'ять значущих символів й буде завершений нуль-термінатором. Усі наступні символи, що вводяться в цей строковий масив, будуть відкинуті. Як видно із прикладу, при використанні функції getline другим параметром слід указувати число, менше або рівне розміру символьного рядка, що вводиться. Більшість функцій роботи з рядками знаходяться в бібліотеці string,h. Основні функції роботи із символьними масивами зведені в таблицю.
Далі самі популярні з наведених функцій будуть розглянуті докладно, однак слід урахувати, що в деяких версіях поставки бібліотек С++ дані функції можуть здійснювати неправильно (або не виконувати зовсім) роботу з національними символами. ВИЗНАЧЕННЯ ДОВЖИНИ РЯДКІВ Дуже часто при роботі з рядками необхідно знати, скільки символів містить рядок. Для з'ясування інформації про довжину рядка в заголовному файлі string.h описана функція strlen. Синтаксис цієї функції має вигляд: size_t strlen ( const char* string ) ; Дана функція як єдиний параметр приймає вказівник на початок рядка string, обчислює кількість символів рядка й повертає отримане беззнакове ціле число (size_t). Функція sizeof повертає значення на одиницю менше, чим приділяється під масив через резервування місця для символу '\0'. Наступний фрагмент демонструє використання функції strlen: char S [ ] = "0123456789" ; int i = strlen ( S ) ; char S [20] = "0123456789" ; // оголошення й ініціалізація рядка довжиною 19 символів cout << "Lenght=" << strlen ( S ) << '\n' ; // вивід на екран Lenght=10 cout << "Size =" << sizeof ( S ) << '\n' ; // вивід на екран Size =20 Часто функція sizeof використовується при введенні рядків як другого параметра конструкції cin.getline, що робить код більш універсальним, тому що не потрібно явної вказівки числа символів, що вводяться. Якщо тепер буде потрібно змінити розмір символьного масиву, досить модифікувати лише одне число при оголошенні рядка символів: char S [20] ; // оголошення рядка довжиною 19 символів cin.getline ( S, sizeof ( S ) ) ; // уведення рядка довжиною не більш 19 символів із клавіатури КОПІЮВАННЯ РЯДКІВ Значення рядків можуть копіюватися з одного в інший. Для цієї мети використовують ряд стандартних функцій, описуваних нижче. Функція strcpy Функція strcpy має прототип: char* strcpy ( char* str1, const char* str2 ) ; і виконує побайтне копіювання символів з рядка, на який вказує str2, у рядок по вказівникові str1. Копіювання припиняється тільки у випадку досягнення нуль-термінатора рядка str2, тому перед копіюванням необхідно впевнитися, що довжина str2 менше або дорівнює довжині str1. А якщо ні, то можливе виникнення помилок, пов'язаних з накладенням даних. Наприклад фрагмент, що випливає, копіює в рядок S значення рядка "String copy": char S [21] ; // оголошення рядка довжиною 20 символів strcpy (S, "String copy" ) ; // копіювання рядка "String copy" у рядок S cout<<S<<'\n' ; // вивід на екран рядка S Можна робити копіювання не всього рядка, а лише окремого її фрагмента ( до кінця рядка). При цьому другий параметр є вказівником на деякий елемент строкового масиву. Необхідно мати через, що ідентифікатор рядка фактично є вказівником на початок рядка. Наприклад фрагмент, що випливає, скопіює в str2 закінчення рядка str1: char S1 [21] = "String copy" ; // оголошення й ініціалізація рядка довжиною 20 символів char S2 [21] ; // оголошення рядка довжиною 20 символів char* ps = S1 ; // оголошення вказівника на символ і // його ініціалізація адресою початку рядка S1 cout << ps << '\n' ; // вивід на екран рядка "String copy" ps += 7 ; // збільшення адреси ps на 7 байт cout << ps << '\n' ; // вивід на екран рядка "copy" strcpy (S2, ps ) ; // копіювання рядка "copy" у рядок S2 cout << S2 <<'\n'; // вивід на екран рядка "copy" Функція strncpy Функція strncpy відрізняється від strcpy тим, що в її параметрах додається ще один аргумент, що вказує кількість символів, не більше якого буде скопійовано. Її синтаксис має вигляд: char* stmcpy ( char* strl, const char* str2, size_t num ) ; Якщо довжина str1 менше довжини str2, відбувається урізування символів: char slong [ ] = "0123456789" ; // оголошення й ініціалізація рядка довжиною 10 символів char sshort [ ] = "abcdef" ; // оголошення й ініціалізація рядка довжиною 6 символів stmcpy ( sshort, slong, 4) ; // копіювання рядка "0123" в у початок рядка sshort cout << sshort << ' \n' ; // вивід на екран рядок "0123ef" Тобто з рядка slong у рядок sshort скопійовано чотири перші символи, затерши тим самим вихідне значення початку короткого рядка. Функція strdup Функція strdup у якості параметра одержує вказівник на рядок джерело, здійснює розподіл пам'яті, копіює у відведену область рядок і повертає вказівник на початок отриманої рядка-копії. Синтаксис функції наступний: char* strdup ( const char* source ) ; У наступному прикладі проводиться копіювання рядка, на який вказує вказівник ps1, у рядок, на який вказує вказівник ps2: char* ps1 = "File not found" ; // оголошення вказівника на символ, // виділення пам'яті для рядка довжиною 14 символів і // ініціалізація вказівника ps1 адресою цього рядка char* ps2 ; // оголошення вказівника на символ ps2 = strdup ( ps1 ) ; // виділення пам'яті для рядка довжиною 14 символів і // ініціалізація вказівника ps2 адресою цього рядка cout << ps2 << '\n' ; // вивід на екран рядка, на який вказує // вказівник ps2: "File not found" cout << strlen ( ps2 ) << '\n' ; // вивід на екран довжини рядка, // на яку вказує вказівник ps2: "14" КОНКАТЕНАЦІЯ РЯДКІВ Конкатенація (або приєднання) рядків досить часто використовується для створення нового рядка символів. Для цієї операції стандартна бібліотека пропонує функції strcat і strncat. Функція strсat Функція strсat має синтаксис: char* strcat ( char* str1, const char* str2 ) ; У результаті роботи функції вміст рядка, на який вказує str2, приєднується до вмісту рядка, на який посилається str1. вказівник, що вертається функцією, str1 вказує на результуючий рядок. При цьому розмір строкового масиву str1 повинна бути достатнім для зберігання об'єднаного рядка. У наступному прикладі рядок S ініціалізується за допомогою функції копіювання strcpy і доповнюється рядком, використовуючи функцію strcat: char S [26] ; // оголошення рядка довжиною 25 символів strcpy ( S, "Press any key ") ; // ініціалізація рядка cout << S << '\n' ; // вивід на екран рядка “Press any key ” strcat ( S, "to continue") ; // додавання в кінець рядка “to continue” cout << S << '\n' ; // вивід на екран рядка “Press any key to continue” Функція strncat Функція strncat також здійснює конкатенацію рядків, однак, приєднує лише зазначене в третьому параметрі кількість символів (беззнакове ціле): Функція strnсat має синтаксис: char* strncat ( char* str1, const char* str2, size_t num) ; Функція повертає вказівник на початок сформованого рядка str1. При цьому розмір строкового масиву str1 повинна бути достатнім для зберігання об'єднаного рядка. Наступний приклад робить конкатенацію рядка str1 із двома першими символами подстроки str2: char S1 [31]="Press any key " ; // оголошення й ініціалізація char S2 [31]="to continue" ; // двох рядків довжиною 30 символів strncat ( S1, S2, 2 ) ; // додавання двох перших символів рядка S2 у кінець рядка S1 cout << S1 << '\n' ; // вивід на екран рядка “Press any key to” ПОРІВНЯННЯ РЯДКІВ Бібліотека функцій string.h пропонує до використання готові функції, що виконують порівняння рядків. Із двох рядків менше та, у якої менше код першого незбіжного символу. Нижче приводяться функції, що виконують посимвольне порівняння двох рядків. Функція strcmp Ця функція робить порівняння рядків, розрізняючи прописні й малі літери. Функція strcmp має синтаксис: int strcmp ( const char* str1, const char* str2 ) ; У якості параметрів функція одержує вказівники на рядки, які рівняються. Після порівняння рядків str1 і str2 дана функція повертає в результаті одне з наступних значень: Ø < 0 - якщо рядок str1 менше, чим str2; Ø = 0 - якщо рядки еквівалентні; Ø > 0 - якщо рядок str2 більше, чим str2. Наступний приклад ілюструє роботу функції strcmp: char S1 [ ] = "Error" ; // оголошення й ініціалізація двох рядків char S2 [ ] = "error" ; int i = strcmp ( S1, S2 ) ; // оголошення змінної типу int і ініціалізація її // результатом порівняння двох рядків cout << "i = " << i << '\n' ; // вивід на екран “i = -1” cout << S1 ; // вивід на екран “Error < error” if ( i>0) cout << " > " ; else { if ( i<0) cout << " < " ; else cout<<" = "; } cout << S2 << '\n' ; У результаті змінної i буде привласнено негативне значення, тому що рядок з S1 менше, чим рядок з S2, з тієї причини, що прописні букви мають код символів менше, чим ті ж символи в нижньому регістрі. Функції stricmp, strcmpi Дані функції порівнюють два рядки, не розрізняючи регістру символів. Функція stricmp і має синтаксис: int stricmp (const char *str1, const char *str2 ) ; Що вертається значення й одержувані параметри ті ж, що й у функції strcmp. Функція strncmp Функція strncmp проводить порівняння певного числа перших символів двох рядків. Регістр символів при цьому враховується. Функція має наступний прототип: int strncmp ( const char* str1, const char* str2, size_t num ) ; Дана функція порівнює num перших символів двох рядків, на які вказують str1 і str2. ПЕРЕТВОРЕННЯ РЯДКІВ Елементи символьних рядків можуть бути перетворені з одного регістру в іншій. Для цього використовуються стандартні функції _strlwr і _strupr. Слід зазначити, що в деяких версіях компіляторів імена даних функцій можуть випливати без провідного символу підкреслення. Функції strlwr, _strlwr Функція strlwr приймає в якості параметра вказівник на рядок символів, перетворить цей рядок до нижнього регістру (рядкові символи) і повертає вказівник на отриманий рядок. Дана функція має наступний прототип: char* strlwr(char* str) ; Наступний фрагмент показує застосування функції strlwr: char S [ ] = "Error" ; // оголошення й ініціалізація рядка strlwr ( S ) ; // перетворення рядка в нижній регістр cout << S << '\n' ; // вивід на екран "error" Функції strupr, _strupr Функція strupr оголошена в такий спосіб: char* strupr ( char* str ) ; Дана функція перетворить рядок символів, на який вказує str, у прописні букви ( до верхнього регістру). У результаті роботи функції вертається вказівник на отриманий рядок. Наведені вище функції перетворення рядків, працюючи з вказівниками, перетворять вихідний рядок, який не завжди може бути відновлена, тому, якщо надалі коді програми буде потрібно скористатися оригіналом символьного рядка, перед використанням функцій strlwr і strupr необхідно зробити копію їх аргументів. Функції CharToOem У консольному додатку рядка кирилиці, що містять символи, некоректно відображаються у вікні додатка. Для рішення задачі відповідного перетворення кодів символів у заголовному файлі windows.h оголошена функція Chartooem, синтаксис якої має такий вигляд: int CharToOem (char* const str1, const char* str2 ) ; Функція робить перетворення кодів символів рядка str1 таким чином, що рядок символів str2 правильно відображає символи кирилиці. При цьому рядок str1 не змінюється, а розмір строкового масиву str2 повинна бути достатнім для зберігання перетвореного рядка. Наступний приклад робить перетворення кодів символів рядка str1 кирилиці, що містить символи, у рядок str2, яка правильно відображається у вікні додатка: #include <iostream.h> #include <windows.h> void main () { char S1 [ ] = "Кирилиця" ; // оголошення й ініціалізація рядка char S2 [80] ; // оголошення рядка довжиною 25 символів Chartooem ( S1, S2 ) ; // перетворення кодів символів кирилиці сout << S1 << '\n' ; // вивід на екран "шЁшыышУр" cout << S2 << '\n' ; // вивід на екран "Кирилиця" } Зміна порядку символів рядка На зворотній Функція обігу рядка strrev міняє порядок проходження символів на зворотний (реверс рядка). Дана функція має прототип: char* strrev ( char* str ) Наступний приклад демонструє роботу функції strrev. char S [ ] = "Hello" ; // оголошення й ініціалізація рядка cout << S << '\n' ; // вивід на екран "Hello" strrev ( S ) ; // реверс рядка cout << S << '\n' ; // вивід на екран "olleh" Ця функція також перетворить рядокроригінал. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Последнее изменение этой страницы: 2018-06-01; просмотров: 277. stydopedya.ru не претендует на авторское право материалов, которые вылажены, но предоставляет бесплатный доступ к ним. В случае нарушения авторского права или персональных данных напишите сюда... |