Смекни!
smekni.com

Мова програмування С++ (стр. 5 из 7)

cin >> nriad >> nstp;

int**a = new int *[nriad];// 1

for (int i=0; i < nriad; i++)// 2

a[i] = new int[nstp];// 3

В операторі 1 оголошується змінна типу ”вказівник на вказівник на int” і виділяється пам’ять під масив вказівників на рядки масиву (nriad – кількість рядків). В операторі 2 організовано цикл для виділення пам’яті під кожен рядок масиву. В операторі 3 кожному елементу масиву вказівників на рядки присвоюється адреса початку ділянки пам’яті, виділеної під рядок двовимірного масиву з кількістю елементів типу int у ній, рівною nstp


8. Символьна інформація та рядки

8.1 ЗБЕРЕЖЕННЯ СИМВОЛЬНОЇ ІНФОРМАЦІЇ

Для символьних даних в C/С++ введено тип char. Для представлення символьної інформації використовуються символи, символьні змінні і текстові константи. Приклади:

const char c=’c’; //символ-константа – займає один байт

char a,b; // символьні змінні, займають по одному байту

const char *s=“Приклад рядка&bsol;n” ; // рядкова константа

Рядок в С++ - це масив символів, що закінчується нуль-символом ‘&bsol;0’. За місцезнаходженням цього символу визначається фактична довжина рядка. Кількість елементів у такому масиві на 1 більше за зображення рядка (рис. 8.1).

A &bsol;0 A
“A”рядок (2 байти) ‘A’символ (1байт)

Рис. 8.1.

Рядок розміщується у масиві або за допомогою операції вводу з клавіатури, або за допомогою ініціалізації.

Приклади:

char s1[10]="string1"; // масив символів з десяти елементів

char s3[]={‘s’,’t’,’a’,‘r’,’t’,’&bsol;0’}; // масив з 6 елементів типу char

сhar *s4="string4"; // вказівник-змінна на рядок

char *s=”String5”; // виділяється 8 байтів для рядка

char *sss=new char[10]; /* виділяється динамічна пам’ять

під 10 елементів типу char*/

strcpy(sss,”Thanks”);// у цю область пам’яті копіюється рядок.


8.2 ФУНКЦІЇ ВВОДУ/ВИВОДУ ПРИ РОБОТІ З РЯДКАМИ

Для вводу і виводу символьних даних у бібліотеці мови С (файл <stdio.h>)визначені наступні функції:

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

int putchar (int c) – розміщує в стандартний вихідний потік символ c.

Приклад:

# include <stdio.h>

void main()

{char c, d;

c=getchar(); putchar(c);

d=getchar(); putchar(d);

}

char* gets(char*s) – зчитує рядок s із стандартного потоку до появи символу ‘&bsol;n’, сам символ ‘&bsol;n’ у рядок не заноситься. Повертає вказівник на цей рядок.

int puts(const char* s) – записує рядок у стандартний потік виводу, додаючи в кінці рядка символ ‘&bsol;n’, у випадку вдалого завершення повертає значення більше або рівне 0 і від’ємне значення у випадку помилки.

Також для вводу/виводу рядка можна використовувати функції scanf/printf, відповідно, задавши специфікатор формату %s:

# include <stdio.h>

void main(){

const int n=10;

char s[n];

scanf(“%s”, s); printf(“%s”, s);}

Ім’я масиву є вказівником-константою на початок рядка, тому не слід застосовувати операцію взяття адреси (&), що зазвичай використовується з функцією вводу scanf. Ввід буде здійснюватися до першого символу пропуску. Для того щоб ввести рядок, який складається з декількох слів, використовується специфікатор %c (символи) із зазначенням у ньому максимальної кількості символів, що вводяться, наприклад:

scanf(“%10c”, s);

При виводі рядка на екран можна в специфікації %s зазначити кількість символів, які відводяться під рядок:

printf(“%15s”, s);

Функції вводу/виводу мови С++, описані у заголовному файлі <iostream.h>:

cin>>s; //ввід рядка зі стандартного потоку до появи першого пропуску.

При введенні, наприклад, рядка “Ваня Іванов” в рядок s буде записано лише перше слово рядка, а саме “Ваня&bsol;0”.

cout<<s; //вивід рядка в стандартний потік до першого пропуску.

Якщо потрібно ввести рядок, який складається з декількох слів, в одну рядкову змінну, використовують методи getline або get класу istream, об’єктом якого є cin. Виклик цього методу здійснюється наступним чином: після імені об’єкту cin ставиться крапка, за якою записується ім’я методу:

#include<iostream.h>

int main()

{const in n=80;

char s[n];

cin.getline(s, n); cout<<s<<endl;

cin.get(s, n); cout<< s}

Метод getline зчитує з вхідного потоку n-1 символів або менше (якщо символ переводу рядка зустрінеться раніше) і записує їх у рядкову змінну s. Символ переводу рядка також зчитується (видаляється) з вхідного потоку, але не записується у рядкову змінну, замість нього розміщується завершальний ’&bsol;0’. Якщо в рядку вихідних даних більше за n-1 символів, наступне введення буде виконуватися з того ж рядка, починаючи з першого символу, що не був зчитаний.

Метод get працює аналогічно, але залишає в потоці символ переводу рядка. До рядкової змінної додається завершальний ’&bsol;0’.

8.3 СПЕЦІАЛЬНІ ФУНКЦІЇ ДЛЯ РОБОТИ З РЯДКАМИ ТА СИМВОЛАМИ

Для рядків не визначено операцій присвоювання, додавання, порівняння, оскільки рядок не є основним типом даних. Для роботи з рядками використовуються спеціальні бібліотечні функції, опис яких міститься у файлі <string.h>. Деякі з цих функцій наведено у таблиці 8.1:

Таблиця 8.1 Функції стандартної бібліотеки для роботи з рядками – файл <string.h>

Прототип функції Короткий опис та використання Пояснення
unsigned strlen(const char*s); Обчислює довжину рядка s.strlen(s); Повертає фактичну довжину рядка, не враховуючи нуль-символ
int strcmp(const char*s1, const char *s2); Порівнює рядки s1 і s2.strcmp(s1, s2); Якщо s1<s2, тоді результат від’ємний, якщо s1= =s2, тоді результат рівний 0, якщо s2>s1 – результат додатний.
int strncmp(const char*s1, const char *s2, n); Порівнює перші n символів рядків s1 і s2.strncmp( s1, s2, n); Якщо n(s1)<n(s2), тоді результат від’ємний, якщо s1= =s2, тоді результат рівний 0, якщо s2>s1 – результат додатний.
char*strcpy(char*s1, const char*s2); Копіює символи рядка s2 у рядок s1. strcpy(s1, s2); Нуль-символ при цьому теж включається
char*strncpy(char*s1, const char*s2, int n); Копіює n символів рядка s2 у рядок s1.strncpy(s1,s2,n); Кінець рядка відкидається. Якщо нуль-символ у вихідному рядку зустрінеться раніше, копіювання припиняється, а решта символів рядка доповнюються ‘&bsol;0’-ми.
char*strcat(char*s1, const char*s2); Дописує рядок s2 до рядка s1.strcat(s1, s2); Перший символ s2 записується на місце нуль-символу рядка s1. До результуючого s1 додається ‘&bsol;0’.
char*strncat(char*s1, const char*s2, size_t n); Дописуються перші n символів рядка s2 до рядка s1.strncat(s1,s2,5); n-символів рядка s2 записується до s1, починаючи з місця нуль-символу s1.
char* strсhr(char*s, int ch) Шукає символ ch у рядку s.strchr(s, ch); Повертає вказівник на перше входження символу в рядок справа. Якщо його немає – повертається NULL
char* strrev(char *s1) Змінює порядок символів у рядку s1 на протилежний.strrev(s1, s2); Дзеркальне відображення рядка s1.
char *strstr(char*s1, char*s2) Шукає підрядок у рядку.strstr(s1, s2); Пошук першого входження s2 у s1. В разі вдалого пошуку повертається вказівник на елемент з s1, з якого починається s2, інакше – NULL.
char *strtok(char*s1, char*s2) Розбиває рядок на лексеми.strtok(s1, s2); Функція повертає вказівник на лексему в s1, відокремлену символом з набору s2 (пробілами або розділовими знаками).

Для роботи з символами у файлі <ctype.h> стандартної бібліотеки визначено функції, наведені в таблиці 8.2:

Таблиця 8.2 Функції стандартної бібліотеки для роботи з символами-файл <ctype.h>

Прототип функції Короткий опис та використання Пояснення
int isalnum(int ch) Перевіряє чи є символ ch буквою або цифрою (A-Z, a-z, 0-9).isalnum(ch); Повертається true, якщо ch є буквою або цифрою, інакше false
int isalpha(int ch) Перевіряє чи є символ ch буквою (A-Z, a-z). isalpha(ch); Повертається true, якщо ch є буквою, інакше false
int isspace(int ch) Перевіряє чи є символ ch пропуском (пробіл, табуляція, символ нового рядка, нової сторінки). isspace(ch); Повертається true, якщо ch є узагальненим пробілом, інакше false
int isdigit(int ch) Перевіряє чи є символ цифрою (0-9).isdigit(ch); Повертається true, якщо ch є цифрою, інакше false
int islower(int ch) Перевіряє чи є символ буквою нижнього регістру (a-z).islower(ch); Повертається true, якщо ch є буквою нижнього регістру, інакше false
int isupper(int ch) Перевіряє чи є символ буквою верхнього регістру (A-Z).isupper(ch); Повертається true, якщо ch є буквою верхнього регістру, інакше false
int ispunct(int ch) Перевіряє чи є символ символом пунктуації (. , : ; ? ! тощо).ispunct(ch); Повертається true, якщо ch є символом пунктуації, інакше false
int tolower (int ch) Повертає символ у нижньому регістрі.tolower (int ch); Одержує символ ch і повертає його у нижньому регістрі
int toupper(int ch) Повертає символ у верхньому регістрі.toupper(int ch); Одержує символ ch і повертає його у верхньому регістрі

Приклад 1:

Дано рядок символів, що складається зі слів, слова відокремлені пропусками. Видалити з рядка всі слова, що починаються з цифри.

#include <iostream.h>

#include <string.h>

#include <ctype.h>

void main()

{const int n=250;// розмірність рядкового масиву

char s[n], // вихідний рядок

w[25], // проміжний масив для збереження слова з рядка

*mas[10];// масив вказівників для збереження слів з рядка

cout<<“&bsol;nBведiть рядок:&bsol;n”;

cin.getline(s, n);

int k=0, t=0, i, len, j;

len=strlen(s);

while(t<len)

{ for(j=0,i=t; isspace(s[i])==0; i++,j++)

w[j]=s[i]; // виокремлюємо слово до пробілу

w[j]=’&bsol;0’;// формуємо кінець слова

strcpy(mas[k],w);// копіюємо слово у масив

k++;// збільшуємо лічильник слів у рядку

t=i+1;// перехід через пробіл до наступного слова у

// вихідному рядку s

}

strcpy(s,” ”);// очищуємо вихідний рядок

for(t=0; t<k; t++)// заповнюємо рядок

if(isalpha(mas[t][0])!=0){// якщо перший символ не цифра

{strcat(s,mas[t]);// дописуємо слово в оновлений рядок