Попередня сторінка Зміст Наступна сторінка Електронні посібники ВНТУ
ЛАБОРАТОРНА РОБОТА №5
РОБОТА З ТЕКСТОВИМИ РЯДКАМИ
Мета роботи
- Вивчити можливості оголошення та ініціалізації рядків.
- Навчитись вводити рядки з клавіатури і виводити їх на дисплей.
- Дослідити основні функції роботи з рядками та реалізовувати найпростіші операції з текстовими рядками.
- Навчитись використовувати основні функції бібліотек мови С для роботи з рядками (масивами символів).
ТЕОРЕТИЧНІ ВІДОМОСТІ
Основні функції роботи з символами та рядками
Стандартна бібліотека мови С володіє багатим і різноманітним набором функцій для обробки символів (табл. 5.1) і рядків (табл. 5.2).
Таблиця 5.1 – Функції для роботи із символами (<ctype.h>)
Прототип функції | Опис |
---|---|
int isalnum(int c); | Перевірка, чи є символ літерою або цифрою |
int isalpha(int c); | Перевірка, чи є символ літерою |
int iscntrl(int c); | Перевірка, чи є символ керуючим |
int isdigit(int c); | Перевірка, чи є символ десятковою цифрою |
int isgraph(int c); | Перевірка, чи є символ видимим |
int isprint(int c); | Перевірка, чи є символ видимим, включаючи пробіл |
int islower(int c); | Перевірка, чи є символ літерою нижнього регістру |
int ispunct(int c); | Перевірка, чи є символ знаком пунктуації |
int isspace(int c); | Перевірка, чи є символ пробільним |
int isupper(int c); | Перевірка, чи є символ літерою верхнього регістру |
int isxdigit(int c); | Перевірка, чи є символ шістнадцятковою цифрою |
int tolower(int c); | Перетворення символу в нижній регістр |
int toupper(int c); | Перетворення символу у верхній регістр |
Таблиця 5.2 – Функції бібліотеки введення/виведення (<stdio.h>)
Прототип функції | Опис |
---|---|
int getchar(void) | Вводить наступний символ зі стандартного пристрою введення і повертає його в форматі цілого. |
char *gets(char *s) | Вводить символи зі стандартного пристрою введення в масив s до тих пір, поки не зустріне символ кінця рядка або індикатор кінця файлу. |
int putchar(int c) | Виводить символ, який зберігається в с. |
int puts(const char *s) | Виводить рядок s та перехід на наступний рядок |
int sprintf(char *buf, const char *format [,arg1, …]) | Виконує форматоване виведення у рядок buf. Параметр format задає спосіб відображення значень змінних arg1, …. Дія функції sprintf аналогічна дії функції printf, але виведення виконується в рядок-буфер, а не на екран. |
int sscanf(const char *s, const char *format [, address1, …]) |
Виконує дії, еквівалентні scanf за винятком того, що введення здійснюється з масиву s, а не з клавіатури. |
Рядкові функції працюють з масивами символів (рядками), що закінчуються символом кінця рядка. У мові С для роботи з рядковими функціями використовується заголовок <string.h>. У ньому визначено тип size_t – тип результату, який утворюється після застосування оператора sizeof() і являє собою різновид цілого без знака. У таблиці 5.3 наведено найбільш популярні і підтримувані більшістю компіляторів функції.
Таблиця 5.3 – Функції роботи з рядками (<string.h>)
Прототип функції | Опис |
---|---|
char *strcpy(char *s1, const char *s2) | Копіює рядок s2 в масив s1. Повертає значення s1. |
char *strncpy(char *s1, const char *s2, size_t n) | Копіює не більше, ніж n символів рядка s2 в масив s1. Повертає значення s1. |
char *strcat(char *s1, const char *s2) | Об’єднує рядок s2 з рядком масива s1. Перший символ рядка s2 переписує символ NULL рядка s1. Повертає значення s1. |
char *strncat(char *s1, const char *s2, size_t n) | Об’єднує не більше, ніж n символів рядка s2 з рядком s1. Перший символ рядка s2 переписує символ NULL рядка s1. Повертає значення s1. |
int strcmp(const char *s1, const char *s2) | Порівнює рядок s1 з рядком s2. Функція повертає 0, значення менше 0 або більше 0, якщо s1 рівна, менше або більше, ніж s2. |
int strncmp(const char *s1, const char *s2, size_t n) | Порівнює n символів рядків s1 і s2. Функція повертає 0, значення, менше 0 або більше 0, якщо s1 відповідно рівний, менший або більший, ніж s2. |
char *strchr(const char *s, int c) | Знаходить позицію першого входження символа с в рядок s. Якщо с знайдено, функція повертає покажчик на с в рядку s. Інакше повертається покажчик NULL. |
char *strrchr(const char *s, int c) | Знаходить позицію останньго входження символу с в рядок s. Якщо с знайдено, то повертається покажчик на с в рядку s. Інакше повертається покажчик NULL. |
size_t strcspn(const char *s1, const char *s2) | Повертає довжину початкового сегмента рядка s1, що містить тільки ті символи, що не входять в s2. |
size_t strspn(const char *s1, const char *s2) | Визначає і повертає довжину початкового сегмента рядка s1, що містить тільки ті символи, що входять в s2. |
char *strstr(const char *s1, const char *s2) | Знаходить позицію першого входження рядка s2 в рядок s1. Якщо знайдено, повертається покажчик підрядка в рядку s1. Інакше повертається покажчик NULL. |
char *strtok (const char *s1, const char *s2) | Послідовні виклики функції виконують розбиття рядка s1 на лексеми (слова), розділені символами, які містяться в s2. При першому виклику функція отримує в якості аргументу рядок s1, а при наступних викликах, щоб продовжити розбиття того ж рядка, першим аргументом передається NULL. При кожному виклику повертається покажчик на поточну лексему рядка s1. Якщо лексем в рядку не залишилось, то повертається NULL. |
size_t strlen(const char *s) | Визначає довжину рядка s (до символу NULL). |
Оскільки в С не передбачений автоматичний контроль порушення меж масивів, вся відповідальність за їх переповнення лягає на програміста.
Приклад розробки програми для роботи з рядками і символами
Задача. З клавіатури вводиться текстовий рядок. Скласти програму, яка:
а) інвертує рядок, подаючи його у зворотному вигляді; б) підраховує кількість чисел у тексті; в) видаляє всі слова, що починаються з цифри.
Формалізація задачі
- Вхідний рядок S представимо у вигляді масиву символів.
- Підрахуємо n – кількість символів у рядку.
- Далі програму розділимо на три послідовних частини.
- Отримання інвертованого рядка:
- підготуємо рядок S1 такого самого розміру n;
- здійснимо в циклі (i=0, …, n-1) присвоєння:
- S1i = Sn-i-1. (тут враховуємо те, що останній символ рядка S дорівнює '\0');
- додаємо в массив S1 символ закінчення (щоб обірвати рядок).
- Виділення окремих слів.
- запам’ятовуємо S в S1 (щоб не зіпсувати початковий рядок);
- переглядаємо рядок S по словах (виділяємо частину рядка до пробілу). Це доцільно зробити в циклі.
- Видалення слів, що починаються з цифри:
- відновлюємо S з S1;
- готуємо рядок S2, в якому будемо зберігати ті слова, що не починаються з цифри;
- переглядаємо рядок S по словах (виділяємо частину рядка до пробілу). Якщо слово починається з цифри, не додаємо його до S2, в іншому випадку – додаємо;
- додаємо в массив S2 символ закінчення (щоб обірвати рядок).
Схема роботи програми
Розробимо загальну схему роботи програми.
Для кожної з частин доцільно розробити окрему схему.
Лістинг програми
#include <stdio.h>
#include <iostream>
using namespace std;
int main()
{
cout << "\n Input String: ";
char s[80];
gets(s);
int n=strlen(s); // довжина рядка
char *s1 = new char[n];
for (int i=0; i<n; i++)// перевертаємо рядок
s1[i]=s[strlen(s)-i-1];
s1[n]='\0';
cout << "\n Reverse String: " << s1;
// виділяємо слова у реченні
strcpy(s1,s); // запамятовуємо початкове речення
cout <<"\n\n\n Words in string: \n";
char *word;
word = strtok(s, " " );
while (word != NULL)
{
printf("\n\t%s",word);
word=strtok(NULL, " ");
}
// ще раз виділяємо слова, але не виводимо ті, що починаються з цифри
strcpy(s,s1); // відновлюємо початкове речення
cout <<"\n\n\n String without first digits: \n";
char *s2 = new char[n];
strcpy(s2,"");
word = strtok(s, " " );
while (word != NULL)
{
if (strpbrk(word,"0123456789")==NULL)
strcat(s2,word);
strcat(s2," ");
word=strtok(NULL, " ");
}
strcat(s2,"\0");
printf("\n\t%s",s2);
delete[] s1;
delete[] s2;
_getch();
return 0;
}
Результат роботи програми
Порядок виконання роботи
- Ознайомитись з теоретичним матеріалом, з функціями стандартних бібліотек для роботи з рядками і символами.
- Дослідити процес реалізації завдань прикладів, відлагодити наведені програму на своєму комп’ютері.
- Розробити власну програму, які реалізує індивідуальне завдання.
- Підготувати звіт, який включатиме:
- варіант і текст індивідуального завдання;
- формалізацію завдання (включаючи математичну модель задачі);
- схему роботи програми;
- лістинг програми;
- роздруківку трьох контрольних прикладів (вигляд екрану з результатами – різні значення вхідних даних);
- висновки.
Варіанти індивідуальних завдань
Задача 1. З клавіатури вводиться текстовий рядок. Розробити програму, яка реалізує вказані дії.
1 |
а) підраховує кількість слів, які мають непарну довжину; б) виводить на екран частоту входження кожної літери; в) видаляє текст, що розміщено в круглих дужках. |
2 |
а) перевіряє, чи співпадає кількість відкритих і закритих дужок у введеному рядку (перевірити для круглих та квадратних дужок); б) виводить на екран найдовше слово; в) видаляє всі слова, що складаються тільки з латинських літер. |
3 |
а) підраховує кількість різних слів, що входять до заданого тексту; б) виводить на екран кількість використаних символів; в) видаляє всі слова, що мають подвоєні літери. |
4 |
а) підраховує кількість слів у тексті; б) виводить на екран слово, що містить найбільшу кількість голосних літер; в) видаляє з тексту всі непотрібні пробіли. |
5 |
а) підраховує кількість розділових знаків у тексті; б) виводить всі слова, що мають парну кількість літер; в) міняє місцями першу і останню літери кожного слова. |
6 |
а) підраховує кількість великих літер у тексті; б) виводить на екран слова, що мають найменшу кількість літер; в) видаляє всі слова, що починаються з малої літери. |
7 |
а) підраховує кількість чисел у тексті (не цифр, а саме чисел); б) виводить на екран всі слова, що складаються тільки з латинських літер; в) видаляє кожне друге слово. |
8 |
а) підраховує кількість цифр у тексті; б) виводить на екран слова, що починаються з приголосних літер; в) знищує всі слова, які починаються і закінчуються за одну й ту ж літеру. |
9 |
а) підраховує кількість слів у тексті, які закінчуються на голосну літеру; б) виводить на екран всі слова, довжина яких менша п'яти символів; в) видаляє всі слова, які містять хоча б одну латинську літеру. |
10 |
а) підраховує кількість слів у тексті, які починаються з голосної літери; б) виводить на екран всі слова, що мають непарну кількість приголосних літер; в) видаляє всі числа з тексту. |
11 |
а) замінює всі великі літери, що входять до тексту на відповідні малі; б) виводить на екран найдовше слово; в) видаляє всі слова, що містять непарну кількість приголосних літер. |
12 |
а) кількість слів, які містять однакову кількість голосних і приголосних літер; б) виводить на екран найдовше слово; в) видаляє з тексту всі слова-паліндроми. |
13 |
а) виводить всі символи, які розташовані після першого символу ":"; б) підраховує кількість речень, що містять непарну кількість слів; в) видаляє з тексту всі слова, які розташовані після ком. |
14 |
а) підраховує кількість слів у кожному реченні; б) виводить на екран найдовше речення; в) видаляє всі слова, передостання літера яких голосна. |
15 |
а) інвертує рядок, подаючи його у зворотному вигляді; б) підраховує кількість чисел у тексті; в) видаляє всі слова, що починаються з голосних літер. |
* Задача 2. Зловмисник не викраде інформацію, про існування якої він не підозрює – ось гасло стеганографії. Карл – геть не зловмисник, однак він найближчими днями святкуватиме свій день народження, тому Аліса і Боб повинні обговорити подарунок, який вони вирішили разом презентувати Карлу.
На шляху їх благородних бажань стала одна перешкода – Боба поселили в гуртожитку в одній кімнаті з Карлом. Переймаючись тим, що Карл може ненароком побачити, про що чатяться Боб з Алісою, Боб вирішив скористатись здобутками стеганографії, приховуючи свої справжні повідомлення, керуючись:
- кожне k-те повторення голосної та кожне l-те повторення приголосної літери кирилиці становлять літери прихованого повідомлення;
- кожна зустріч латинської літери 1, вставленої в тексті замість аналогічної літери кирилиці, позначає, що до приблизної вартості подарунку необхідно додати десять гривень, а кожна латинська літера 2 – одну гривню.
Напишіть програму, яка допоможе Алісі читати приховані повідомлення Боба.
Варіант | l | k | літера 1 | літера 2 | Варіант | l | k | літера 1 | літера 2 | |
1 | 4 | 6 | a | y | 9 | 4 | 5 | a | e | |
2 | 3 | 8 | x | i | 10 | 3 | 4 | x | a | |
3 | 5 | 7 | i | e | 11 | 5 | 6 | i | x | |
4 | 2 | 5 | y | a | 12 | 2 | 8 | y | o | |
5 | 4 | 4 | a | x | 13 | 4 | 7 | a | e | |
6 | 3 | 6 | x | o | 14 | 3 | 5 | x | i | |
7 | 5 | 8 | i | y | 15 | 2 | 4 | i | a | |
8 | 2 | 7 | y | i |
Контрольні питання
- Який заголовочний файл використовується у мові С для роботи з символами?
- Наведіть приклади використання функцій обробки символів.
- Які функції існують для введення і виведення символів?
- Наведіть основі функції введення\виведення рядків і їх призначення. Який заголововчний файл містить опис цих функцій?
- Чим відрізняються різні функції введення\виведення рядків? Наведіть приклади їх використання.
- Який заголовний файл використовується у мові С для обробки рядків?
- Назвіть основні функції роботи з рядками.
- Як можна оголосити рядок? Наведіть різні способи оголошення та ініціалізації рядків.
- Для чого у рядках використовується завершуючий символ?
- Як отримати довжину рядка?
- Як компілятор мови С контролює вихід за межі масиву символів?
- Як можна запрограмувати виділення слів у введенному реченні?
- Яким чином можна об’єднати рядки символів та виділити підрядки за певними ознаками? Наведіть приклади.