- •Int main() /* головна обов’язкова функція, де ключове слово int означає, що функція main() повертатиме у точку виклику результат цілого типу*/ 6
- •Засоби розробки с програм
- •Директиви препроцесора.
- •Using namespace std; // вказуємо, що будемо працювати з іменами із стандартної бібліотеки
- •Запитання
- •Тема 2. Данні
- •Команда присвоєння. Правила узгодження типів.
- •Запитання
- •Тема 3. Операції та вирази
- •Тема 4. Потоки. Введення - виведення даних
- •Форматування даних
- •Введення-виведенні засобами бібліотеки сstdіo
- •Тема 5. Адреси даних. Вказівники. Динамічна пам’ять
- •Тема 6. Файли
- •Тема 7. Розгалуження
- •Логічні вирази та логічні операції.
- •Команда ?
- •Тема 8. Цикли
- •Команда циклу з післяумовою do-while має вигляд
- •Тема 9. Функції (1)
- •Тема 10. Функції (2)
- •Тема 11. Масиви
- •Тема 12. Рядки
- •Тема 13. Структури, списки, стеки, черги, об’єднання
- •Тема 14. Виняткові ситуації
- •Http://www.Rate1.Com.Ua/strannosti/2633/ Самі фатальні помилки в програмному забезпеченні
- •Помилки під час виконання (виняткові ситуації, виключення) Exceptions - це помилки, що виникають у випадку, коли програма намагається виконати неприпустиму операцію.
- •Тема 15. Графіка
- •Написание простых графических программ
- •Http://www.Rsdn.Ru/article/opengl/ogltut2.Xml Графическая библиотека OpenGl
Тема 12. Рядки
Рядки символів і дії з ними. На відміну від інших мов програмування у C++ не визначено спеціального типу для опрацювання рядків. Рядок символів розглядається як масив елементів типу char, який закінчується символом ’\0’ (нуль-символ), що є ознакою кінця рядка. Такі рядки називають ASCII-рядками. Сталі типу рядок записують у лапках, наприклад, "Львівська політехніка", "студенти", " " - рядок, що містить один символ-пропуск. У сталих рядках нуль-символ дописується автоматично.
Зауваження 1. Більшості компіляторів мови C++ автоматично додає нуль-символ у кінець рядка, тому зазначати його не обов’язково.
Масиви символів оголошують так:
char <назва рядка>[довжина рядка];
вами символів, то назва рядка є вказівником на його перший елемент (на перший символ).
Приклад 1. Розглянемо оголошення та ініціалізацію рядків
const char text1[] = "Ми вивчаємо програмування";
char slovo[] = “University";
char fraza1[11], fraza2[40];
Тут оголошено сталу text1, яка має значення "Ми вивчаємо програмування", символьні масиви: slovo (без зазначення розміру), fraza1 (може містити до 10 символів) та fraza2 (до 39 символів).
Символьний масив slovo ще можна оголосити так:
char slovo[11] = "University”; або так
char slovo[] = {'U', 'n', 'і', ' v' , 'e', 'r', ' s',' i', 't', 'y', '\0'};
Тут потрібно вручну записати нуль-символ, інакше компілятор трактуватиме змінну slovo не як рядок, а як масив.
Рядки можна опрацьовувати посимвольно за допомогою вказівників або назви масиву, наприклад, так:
for (int n = 0; n < 11; n++)
*(fraza1 +n) = *(slovo+n);
cout<<fraza1;
Змінній frazal надається значення "University" і ця фраза виводиться на екран. Інакше це можна зробити так:
for (int n = 0; n < 11; n++)
fraza1[n] = slovo[n];
cout<<fraza1;
Увести весь масив символів можна за допомогою команди
сіn>> <назва масиву>;
Якщо рядок даних містить символ пропуску, то команда сіn>> зчитає дані лише до першого пропуску. Щоб зчитати весь рядок до символу вводу, необхідно застосувати команду
cin.get(<нaзва рядка>, <максимальна довжина рядка>);
Наприклад, cin.get(fraza2, 40). Зчитати символ вводу можна так: cin.get(). Зчитати рядок разом із символом вводу можна одним із способів:
cin.get(fraza2, 40); cin.get()
cin.get(fraza2, 40).get()
cin.getline(fraza2, 40).
Вивести значення рядка на екран можна за допомогою команди
cout<< <назва рядка>;
Посимвольно вводити чи виводити елементи рядка можна за допомогою команд циклу for або while. Наприклад,
for (int n = 0; n < 11; n++)
cin>> *(fraza1 + n);
В кінці рядка необхідно поставити нуль-символ, тобто *(fraza1 + n + 1) = '\0';
У бібліотеці conio.h визначені стандартні функції введення-виведення рядків. Наприклад, getc(), getchar() зчитують по одному символу рядка, введеного з клавіатури, putc() та initchar() виводять окремі символи рядка тощо. У бібліотеці stdio.h описані функції для введення gets() та виведення puts() усього рядка. Детальніше про ці та інші функції написано у довідниках.
Функції для опрацювання рядків. Для опрацювання масивів символів у мові C++ є стандартні функції, які описані у модулі string.h. Розглянемо деякі з них.
strlen(<pядок>) - визначає фактичну кількість символів у рядку, застосовується у виразах; strcat(r1, r2) - команда з’єднання рядків r1, r2 в один рядок, результат присвоює змінній r1; strncat(r1, r2, n) - до змінної r1 додає перших n символів рядка r2;
strcpy(r1, r2) - копіює символи з рядка r2 в рядок r1;
strncpy(r1, r2, n) - копіює перших n символів рядка r2 в рядок r1;
strchr(r1, <символ>) - визначає перше входження деякого символу у рядок r1 так: повертає рядок, який починається від першого входження заданого символу до кінця рядка r1, застосовується у виразах;
strrchr(r1, <символ>) - визначає останнє входження заданого символу у рядок, застосовується у виразах;
strspn(r1, r2) — визначає номер першого символу, який входить у рядок r1, але не входить у рядок r2, застосовується у виразах;
strstr(r1, r2) — визначає в рядку r1 підрядок, що починається з першого входження рядка r2 у рядок r1, застосовується у виразах;
strtok(r1, r2) - визначає частину рядка r1, яка закінчується перед першим однаковим символом рядків r1 та r2;
strnset(r1, <символ>, n) - вставляє n разів заданий символ перед рядком r1, застосовується у виразах;
strupr(r1) - перетворює усі малі літери рядка у великі;
strlwr(r1) - перетворює усі великі літери рядка у малі;
strrev(r1) - записує рядок у зворотному порядку.
Приклад 2. Розглянемо результати застосування функцій до таких змінних:
char Lviv[] = "Львівська політехніка",
Un [30] = "НУ ", r1 [30] ="";
char *р; int n;
Застосування функцій |
Результат |
n = strlen(Lviv) |
n=21 |
strcat(Un, Lviv) |
Un = "НУ Львівська політехніка" |
strncat(Un, Lviv, 10) |
r1 = "НУ Львівська" |
strcpy(r1, Lviv) |
r1 = "Львівська Політехніка" |
strncpy(r1, Lviv, 10) |
r1 = "Львівська" |
p = strchr(Lviv, 'П') |
р = "політехніка" |
p = strrchr(Lviv, 'i') |
р = "іка" |
n = strspn(Lviv, "Львів") |
n = 5 |
p = strstr(Lviv, "тех") |
р = "техніка" |
p = strtok(Lviv, "kc") |
р = "Львів" |
p = strnset(Lviv, 'x', 10) |
р = "ххххххххххполітехніка" |
p = strupr("I Love You") |
р = "I LOVE YOU"" |
p = strlwr("I Love You") |
p = і love you" |
p = strrev("техніка") |
р = "акінхет" |
Зауваження 2. Функції перетворення літер strlwr і strupr діють лише для латинського алфавіту. Крім того, у деяких версіях мови C++ ці функції можуть записуватись інакше: _strlwr, _strupr.
У бібліотеці stdlib.h є стандартні функції перетворення типів даних. Зокрема,
функція atoi(r1) перетворює рядок символів r1 у дане цілого типу int,
функція itoa(<числове дане>, r1, <система числення>) - дане цілого типу int у рядок r1. Для перетворення даних типу double у рядок символів визначена
функція gcvt(<числове дане>, <кількість знаків у числі>, r1), а обернену дію виконує
функція strtod.
Приклад 3. Розглянемо результати дії функцій для оголошених нижче змінних.
int n; double f; char r1 [5], *p;
Застосування функції |
Результат |
n = atoi("12") |
n = 12 |
itoa(12, r1, 10) |
r1 ="12" |
gcvt(-3.14, 4, r1) |
r1 =-3.14 |
f = strtod("-3.1415", &p); |
f = -3.1415 |
Рядки символів можна порівнювати між собою. Два рядки порівнюють зліва направо посимвольно, причому 'А' < 'В', 'В' < 'С тощо. Більшим уважається символ, який розміщений в алфавіті дальше (він має більший номер у таблиці кодів ASCII). Для порівняння рядків у модулі string.h є такі функції:
strcmp(r1, r2) - порівнює рядки символів r1 і r2 з урахуванням регістра для латинського алфавіту;
stricmp(r1, r2) - порівнює рядки r1 і r2, не розрізняючи великих і малих літер латинського алфавіту.
Результатом виконання цих функцій є
від’ємне число (якщо рядок r1 менший від рядка r2),
0 (якщо рядки однакові)
додатне число (рядок r1 більший за рядок r2).
Приклад 4. Розглянемо результат дії функцій
Функція |
Результат |
n = strcmp("Becнa", "весна") |
n=-32 |
n = strcmp("вecнa", "Весна") |
n =32 |
n = strcmp("Becнa", "Весна") |
n =0 |
n = stricmp("Becнa", "весна") |
n =-32 |
n = stricmp("Vesna", "vesna") |
n = 0 |
Задача 1 (про довжину фрази). Увести рядок символів та ми визначити його довжину.
Зробимо це двома способами:
за допомогою вказівника типу char і виділення динамічної пам’яті:
#include <iostream> // Довжина рядка символів
using namespace std;
int main(int argc, char** argv) {
char *s; // Оголошуємо вказівник на рядок
s = new char[50]; // Виділяємо пам'ять для введення рядка
cin >> s;
int d = 0;
while (*s++) d++;
cout<< d;
}
визначивши різницю адрес першого й останнього символів:
#include <iostream> // Довжина рядка символів
using namespace std;
int main(int argc, char** argv) {
char *s, *p; //Оголошуємо вказівники
s = new char[50]; // Виділяємо пам'ять для введення рядка
cin>> s;
p = s; // Вказівник р вказує на перший символ рядка
while (*s++); int d; // Вказівник s тепер вказуватиме на останній символ рядка
d = s - p-1; // Визначаємо довжину рядка як різницю адрес
cout<< d;
}
Задача 2 (про пошук слова у фразі). Нехай задано рядок "Скоро будуть канікули". Визначити довжину рядка. Вивести на екран фразу з другого слова цього рядка.
#include <iostream> // Пошук другого слова за допомогою функцій
#include <string.h>
using namespace std;
int main(int argc, char** argv) {
char r1[] = "Скоро будуть канікули";
char *p;
cout << r1 << "\n";
cout << "Довжина рядка r1 = " << strlen(r1) << "\n";
p = strchr(r1, ' '); // Встановлюємо вказівник p на перший пропуск у рядку r1
strtok(p,""); //З рядка р вилучаємо всі символи після його першого пропуску
cout<< p;
}
Задача 3. Вивести друге слово фрази задачі 2, при цьому рядок розглядається як масив символів і функції для роботи з рядками не використовуються.
#include <iostream> // Рядок як масив символів
#include <conio.h>
#include <cstring>
using namespace std;
int main(int argc, char** argv) {
char r1[] = "Скоро будуть канікули";
char *p;
int n1, n2, k, m;
m = 0;
k = strlen(r1);
for (int i=0;i<k;i++) // Переглядаємо всі символи рядка
if (r1[i] ==' ') { //Шукаємо пропуск
m++;
if (m == 1) //Визначаємо номери першого
n1 = i;
if (m == 2) // та другого пропусків
n2 = i;
}
for (int i=n1+1;i<n2-1;i++)// Виводимо слово між двома пропусками
cout<< r1 [i];
getch();
}
Задача 3 (про столиці). Введіть п’ять назв столиць європейських країн. Упорядкуйте їх за алфавітом. Виведіть упорядкований масив виведіть на екран.
#include <iostream> // Столиці країн
#include <cstring>
#include <cstdlib>
#define N 5
using namespace std;
int main(int argc, char** argv) {
char p[N][16]; char m[16]; // Оголошуємо N вказівників на рядки довжиною до 15 символів
for (int i = 0; i < N; i++)
cin>> *(p +i); // Вводимо рядок і
for (int i = 0; i < N - 1; i++) {
for (int j = 0; j < N - i; j++) {
if (strcmp(p[j], p[j+1]) > 0) {
strcpy(m, p[j]); // Порівнюємо рядки і у разі потреби, міняємо їх місцями
strcpy(p[j], p[j+1]);
strcpy(p[j+1], m);
}
}
}
for (int i=0;i<N;i++)
cout<< p[i] << "\n";
}
Криптографічні задачі. Текстові функції застосовують для розв’язування задач кодування даних з метою збереження секретності інформації. Існує наука - криптографія,де вивчаються і створюються різні алгоритми кодування інформації. Основні задачі криптографії - це шифрування тексту, передача його на відстань і дешифрування. Це використовується у банківських справах, у воєнних цілях, у діяльності різних фірм, під час пересилання інформації в локальних чи глобальних мережах тощо.
Древнєримський імператор Цезар кодував свої секретні вказівки так: кожна літера тексту замінювалась на четверту після неї літеру з алфавіту. Такий шифр називається в криптографії шифром зі сталим зміщенням (тут 4), або шифром з одним ключем.
Задача 5 (про шифр Цезаря). Скласти програму для кодування деякого тексту до 50 символів шифром Цезаря, замінивши кожну літеру на 4-ту (наприклад, четверту) після неї літеру з алфавіту. Під алфавітом розуміти таблицю кодів ASCII.
#include <iostream>// Програма Код Цезаря
#include <cstring>
using namespace std;
int main(int argc, char** argv) {
char a[50];
cout<< "Введіть текст\n";
cin.get(a, 50);
for (int k, n = 0; n < strlen(a); n++) {
k = *(a+n) + 4; *(a + n) = k;
}
cout<< a;
}
Задача 5 (про заміну слів). Скласти програму, яка скрізь у заданому тексті mytext замінить деяке слово іншим словом такої ж довжини (word1 на word2).
#include <iostream> // Програма заміна слів
#include <cstring>
using namespace std;
int main(int argc, char **argv) {
char word1 [5], word2[5], mytext[50]; char *p;
cout <<"Введіть текст\n";
cin.get(mytext, 50);
cout << "Введіть шукане слово\n";
cin>> word1;
cout<< "Введіть інше слово\n";
cin >> word2;
int k = strlen(word1);
p = mytext; // Встановлюємо вказівник р на початок рядка mytext
for (int і = 0; і < strlen(mytext) - k; і++) { // Опрацьовуємо посимвольно рядок р
p = strstr(p, word1); // Знаходимо перше входження word1 у рядку р
if (p == NULL) break; //Якщо такого входження немає, то виходимо з циклу
for (int j=0; j < k; j++)
*(p + j) = *(word2 + j);// У рядку р замінюємо word1 на word2
}
cout<< mytext;
}
Вправи
Складіть програму розв’язування задачі 1, використавши статичний масив та функцію srtlen.
Уведіть фразу з кількох слів і виведіть її так, щоб усі слова були зображені в зворотному порядку, зберігши порядок слів, двома способами: а) з використанням функцій з бібліотеки string.h; б) без використання функцій з бібліотеки string.h. Наприклад, фразу "заняття з програмування" треба вивести так: "яттяназ з яннавумаргорп" (модифікуйте для цього програму Рядок як масив символів).
Розв’яжіть задачу про столиці країн без застосування функцій з модуля string.h.
Модифікуйте програму Код Цезаря, щоб можна було зашифрувати текст, уведений у декілька рядків.
Складіть програму розшифровування тексту, закодованого кодом Цезаря.
Складіть програму кодування тексту так: перший символ замінити на k-й, що розміщений в алфавіті після нього (тобто замінити з кроком заміщення k), кожний наступний символ замінювати з кроком зміщення на т одиниць більшим, ніж попереднє зміщення. Алфавіт (таблицю кодів чи її фрагмент) розглядати циклічно. Наприклад, обмежимося алфавітом 0, 1, 2, 3, 4, 5, 6, 7, 8, 9. Для k = 2, т = 1 чисельність військового гарнізону 12290 вояків буде зашифрована числом 35646. Такий шифр називається шифром зі змінним зміщенням (або шифром з двома ключами).
Запишіть програму Заміна слів без використання функцій з бібліотеки string.h.
Закодуйте фразу так: вилучіть з неї пропуски та коми, інші символи продублюйте. Вивести результат.
Масив зі 100 рядків і 10 стовпців заповніть цілими числами, що вводяться з клавіатури. Якщо чергове число менше від 0, заповнення такого рядка припиніть. Після чисел у кожному рядку запишіть ще одне? число - кількість чисел у ньому. Виведіть масив.
Розв’яжіть задачі № 16, 17 і 18 з розділу "Задачі" вашого варіанта двома способами:
а) з використанням функцій з бібліотеки string.h;
б) без використання функцій з бібліотеки string.h.
