Студопедия

КАТЕГОРИИ:

АвтоАвтоматизацияАрхитектураАстрономияАудитБиологияБухгалтерияВоенное делоГенетикаГеографияГеологияГосударствоДомЖурналистика и СМИИзобретательствоИностранные языкиИнформатикаИскусствоИсторияКомпьютерыКулинарияКультураЛексикологияЛитератураЛогикаМаркетингМатематикаМашиностроениеМедицинаМенеджментМеталлы и СваркаМеханикаМузыкаНаселениеОбразованиеОхрана безопасности жизниОхрана ТрудаПедагогикаПолитикаПравоПриборостроениеПрограммированиеПроизводствоПромышленностьПсихологияРадиоРегилияСвязьСоциологияСпортСтандартизацияСтроительствоТехнологииТорговляТуризмФизикаФизиологияФилософияФинансыХимияХозяйствоЦеннообразованиеЧерчениеЭкологияЭконометрикаЭкономикаЭлектроникаЮриспунденкция

Зміна порядку символів рядка На зворотній




ОПЕРАЦІЇ З РЯДКАМИ

МАСИВИ СИМВОЛІВ в C++

У стандарт C++ включена підтримка декількох наборів символів. Традиційний 8 бітовий набір символів називається "вузькими" символами. Крім того, включена підтримка 16 бітових символів, які називаються "широкими". Для кожного із цих наборів символів у бібліотеці є своя сукупність функцій.

 Як і в С , для символьних рядків в C++ не існує спеціального строкового типу. Замість цього рядка в C++ представляються як масиви елементів типу char, що закінчуються термінатором рядка символом з нульовим значенням ('\0'). Рядки, що закінчуються нуль-термінатором, часто називають Ascii Рядками. Символьні рядки складаються з набору символьних констант, взятих в подвійні лапки:

"Це рядок символів..."

У таблиці наведений набір констант, що застосовуються в C++ у якості символів.

прописна буква  від 'А' до 'Z', від 'А' до 'Я'
 мала літера  від 'а' до 'z', від 'а' до 'я'
цифра  від '0' до '9'
порожнє місце горизонтальна табуляція '\9',  переклад рядка (код ASCII 10),  вертикальна табуляція (код ASCII 11),  переклад форми (код ASCII 12),  повернення каретки (код ASCII 13)
символи пунктуації ! ” # $ % & ’ () * +, – . / : ;  < = > ? @ [ \ ] _ { | } ~
керуючий символ усі символи з кодами від 0 до 1F  і символ з кодам 7F
пробіл символ пробілу (код ASCII 32)
шістнадцятирічна цифра  від '0' до '9', від 'А' до 'F', від 'a' до 'f'

При оголошенні строкового масиву необхідно брати до уваги наявність термінатора наприкінці рядка, відводячи тим самим під рядок на один байт більше:

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. Основні функції роботи із символьними масивами зведені в таблицю.

Найменування Короткий опис
strlen повертає довжину рядка в байтах, не враховуючи  нульовий термінатор
strcpy копіює рядок2 у рядок1
strncpy копіює задане число символів рядка2 у рядок1
strdup розподіляє пам'ять і робить копію рядка
strcat приєднує рядок2 у кінець рядка1
strncat приєднує задане число символів рядка2  у кінець рядка1
strcmp порівнює рядок1 з рядком2, розрізняючи прописні  й малі літери
stricmp  strcmpi порівнює рядок1 з рядком2, не розрізняючи прописні й малі літери
strncmp порівнює задане число символів двох рядків, розрізняючи прописні й малі літери
strnicmp  strncmpi порівнює задане число символів двох рядків, не розрізняючи прописні й малі літери
strlwr  _strlwr перетворить усі символи рядка в малі літери
strupr  _strupr перетворить усі букви рядка в прописні букви
Chartooem робить перетворення кодів символів str1 таким чином, що рядок str2 правильно відображає символи кирилиці
strrev реверс рядка
strchr повертає позицію першого входження символу в рядок
strrchr відшукує останнє входження символу в рядку
strspn повертає позицію в рядку першого символу, який не належить заданому набору символів
strcspn повертає позицію першого входження символу із заданого набору символів
strpbrk відшукує місце першого входження будь-якого символу із заданого набору
strstr відшукує місце першого входження рядка2 у рядок1
strtok повертає вказівник на лексему, обмежену заданим роздільником
strnset поміщає заданий символ у задане число позицій рядка
strset поміщає символ в усі позиції рядка
strerror повертає по заданому номеру системної помилки вказівник на рядок тексту повідомлення про помилку
strerror повертає вказівник на рядок, утворену об'єднанням довільного рядка й повідомлення про помилку в бібліотечній функції
isalnum(c) істина, якщо символ c є буквою або цифрою
isalpha(c) істина, якщо символ c є буквою
isascii(с) істина, якщо код символу з <= 127
iscntrl(с) істина, якщо з – керуючий символ
isdigit(c) істина, якщо з – символ десяткової цифри
isgraph(с) істина, якщо з – символ, що друкується (код від 33 до 126)
islower(с) істина, якщо c – мала літера
isprint(с) істина, якщо з – символ, що друкується (код від 33 до 126 ) або пробіл
ispunct(с) істина, якщо з – символ пунктуації
isspace(с) істина, якщо з – символ порожнього місця або пробілу
isupper(c) істина, якщо c – прописна буква
isxdigit(c) істина, якщо з – символ шістнадцятирічна цифра
toascii(c) повертає код з або 128, якщо код c більше 127
_tolower(c) перетворить символ прописної букви в символ рядкової. Використовується, якщо точно відомо, що c – прописна буква. Повертає код рядкової букви
tolower(c) перетворить символ прописної букви в символ рядкової, не змінюючи всі інші символи. На відміну від tolower спочатку перевіряє, чи є символ прописною буквою. Якщо ні, то  символи не перетворяться. Повертає код рядкової букви
_toupper(c) перетворить символ рядкової букви в символ прописної. Використовується, якщо точно відомо, що c – мала літера. Повертає код прописної букви
toupper(с) перетворить символ рядкової букви в символ прописний, не змінюючи всі інші символи. На відміну від toupper, спочатку перевіряє, чи є символ малою літерою. Символи, що не є малими літерами не перетворяться. Повертає код прописної букви

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

ВИЗНАЧЕННЯ ДОВЖИНИ РЯДКІВ

Дуже часто при роботі з рядками необхідно знати, скільки символів містить рядок. Для з'ясування інформації про довжину рядка в заголовному файлі 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; просмотров: 199.

stydopedya.ru не претендует на авторское право материалов, которые вылажены, но предоставляет бесплатный доступ к ним. В случае нарушения авторского права или персональных данных напишите сюда...