МІНІСТЕРСТВО ОСВІТИ І НАУКИ УКРАЇНИ
Національний університет “Львівська політехніка”
МАСИВИ СИМВОЛІВ (РЯДКИ) В МОВІ ПРОГРАМУВАННЯ С
Інструкція
до Лабораторної роботи № 5
з курсу “Проблемно-орієнтовані мови програмування”
для студентів базового напрямку 6.08.04
"Комп’ютерні науки"
ЗАТВЕРДЖЕНО
на засіданні кафедри
Системи автоматизованого проектування
Протокол № 1 від 31 серпня 2009 р.
ЛЬВІВ 2009
Масиви символів (рядки) в мові програмування С
Інструкції до лабораторної роботи № 5 з курсу “Проблемно-орієнтовані мови програмування” для студентів базового напрямку 6.08.04 "Комп’ютерні науки“
Укл. М. І. Андрійчук, І. І. Чура. -Львів: НУ “ЛП”, 2009 р. - 13 с.
Укладачі М. І. Андрійчук, доц., к. ф.-м. н.
І. І. Чура, доц., к.т.н.
Відповідальний за випуск С. П. Ткаченко, канд. техн. наук, доц.
Рецензенти М. В. Лобур, доктор техн. наук,
В. І. Каркульовський, канд. техн. наук
1. МЕТА РОБОТИ
Мета роботи - навчитися використовувати символьні масиви для розв’язання задач роботи зі стрічками.
2. ТЕОРЕТИЧНІ ВІДОМОСТІ
Рядки символів і дії з ними
На відміну від інших мов програмування у C не визначено спеціального типу для опрацювання рядків. Масив символів (чи рядок або стрічка) розглядається як масив елементів типу char, який закінчується символом '\0' (нуль-символ) що є ознакою кінця рядка. Такі рядки називають ASCII-рядками. Сталі типу рядок записують у лапках, наприклад, "Львівська політехніка", "студенти", “ “ - рядок, що містить один символ-пропуск. У сталих рядках нуль-символ дописується автоматично
Зауваження 1. Більшості компіляторів мови C додає нуль-символ у кінець рядка, тому зазначати його не обов'язково.
Масиви символів оголошують так:
char <назва рядка>[довжина рядка];
Під час оголошення символьного масиву необхідно до фактичної довжини рядка додати одиницю для нульового символу (але не у всіх компіляторах). Якщо масив символів оголошують й ініціалізують одночасно, то довжину можна не зазначати, компілятор визначить її. Оскільки рядки є масивами символів, то назва рядка є вказівником на його перший елемент (на перший символ).
Приклад 1. Розглянемо оголошення та ініціалізацію рядків
const char text1[] = "Ми вивчаємо програмування";
char slovo[] = "University";
char fraza1[11], fraza2[40];
Тут оголошено сталу textl, яка має значення "Мови програмування", символьні масиви: slovo (без зазначення розміру), frazal (може містити до 10 символів) та fraza2 (до 39 символів).
Символьний масив slovo ще можна оголосити так:
char slovo[11] = "University"; або так
char slovo[ ] = {'U’, 'n’, ‘i’ , ‘v’, ‘e’, ‘r’, ‘s’, 'і', ‘t’, ‘у’, ‘\0’};
Тут потрібно вручну записати нуль-символ, інакше компілятор трактуватиме змінну slovo не як рядок, а як масив.
Рядки можна опрацьовувати посимвольно за допомогою або назви масиву, наприклад, так:
for (int n = 0; n < 11; n++) *(fraza1+n) = *(slovo+n);
cout << frazal;
Змінній fraza1 надається значення "University" і ця фраза виводиться на екран. Інакше це можна зробити так:
for (int n = 0; n < 11; n++)
fraza1 [n] = slovo[n]; cout << fraza1;
Ввести весь масив символів можна за допомогою команди
сіn >> <назва масиву>;
Якщо рядок даних містить символ пропуску, то сіn >> зчитає дані лише до першого пропуску. Щоб весь рядок до символу вводу, необхідно застосувати
cin.get(<назва рядка>, <максимальна довжина рядка>);
Наприклад, 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++) сіп >> *(fraza1 + n);
В кінці рядка необхідно поставити нуль-символ, тобто
*(fraza1+n+1)=’\0’;
У бібліотеці conio.h визначені стандартні функції введення-виведення рядків. Наприклад, getc ( ), getchar ( ) зчитують по одному символу рядка, введеного з клавіатури, putc ( ) та putchar ( ) виводять окремі символи рядка тощо. У бібліотеці stdio.h описані функції для введення gets ( ) та виведення puts ( ) усього рядка. Детальніше про ці та інші функції написано у довідниках.
Функції для опрацювання рядків
Для опрацювання масивів символів у мові C є стандартні функції, які описані у модулі string.h. Розглянемо деякі з них.
strlen(<рядок>) - визначає фактичну кількість символів у рядку, застосовується у виразах;
strcat(r1, r2) - команда з'єднання рядків ґі, г2 в один рядок, результат присвоює змінній r1;
strncat(r1, r2, п) - до змінної г1 додає перших n символів рядка г2,
strcpy(r1, r2) - копіює символи з рядка г2 в рядок г1,
strncpy(r1, r2, n) - копіює перших n символів рядка г2 в рядок г1,
strchr(r1, <символ>) - визначає перше входження деякого символу у рядок г1 так: повертає рядок, який починається від першого входження заданого символу до кінця рядка М, застосовується у виразах;
strrchr(r1, <символ>) - визначає останнє входження заданого символу у рядок, застосовується у виразах;
strspn(r1, r2) - визначає номер першого символу, який входить у рядок г1, але не входить у рядок г2, застосовується у виразах;
strstr(r1, r2) - визначає в рядку г1 підрядок, що починається з першого входження рядка г2 у рядок ґі, застосовується у виразах;
strtok(r1, r2) - визначає частину рядка г1, яка закінчується перед першим однаковим символом рядків r1 та г2;
strnset(r1, <символ>, n) - вставляє n разів заданий символ перед рядком г1, застосовується у виразах;
strupr(r1) - перетворює усі малі літери рядка у великі;
strlwr(rl) - перетворює усі великі літери рядка у малі;
strrev(rl) - записує рядок у зворотному порядку.
Приклад 2. Розглянемо результати застосування функцій до таких змінних:
char Lviv[ ] = "Львівська політехніка",
Un [З0] = "НУ ",
r1 [30] = “ ";
char *p; 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 = "політехніка"
p = strrchr(Lviv, Ї)
p = "іка" .
n = strspn(Lviv, "Львів")
n = 5
j> = strstr(Lviv, "тех")
p = "техніка"
p = strtok(Lviv, "кс")
p = "Львів"
p = strnset(Lviv, 'x', 10)
p = "ххххххххххполітехніка"
p = strupr("l Love You")
p = "і love you"
p = strlwr("l Love You")
p = "I LOVE YOU"
p = strrev(“тexнiкa")
p = "акінхет"
Зауваження 2. Функції перетворення літер strlwr і strupr діють лише для латинського алфавіту. Крім того, у деяких версіях мови C ці функції можуть записуватись інакше: _strlwr, _strupr.
У бібліотеці stdlib.h є стандартні функції перетворення типів даних. Зокрема, функція atoi(r1) перетворює рядок символів г1 у дане цілого типу int, а функція itoa(<числове дане>, г1, <система числення>) - дане цілого типу int у рядок г1. Для перетворення даних типу double у рядок символів визначена функція gcvt(<числове дане>, <кількість знаків у числі>, г1), а обернену дію виконує функція 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) - порівнює рядки символів г1 і г2 з урахуванням регістра для латинського алфавіту;
stricmp(r1, r2) - порівнює рядки г1 і г2, не розрізняючи великих і малих літер латинського алфавіту.
Результатом виконання цих функцій є від'ємне число (якщо рядок г1 менший від рядка г2), 0 (якщо рядки однакові) або додатне число (рядок г1 більший за рядок г2). Приклад 4. Розглянемо результат дії функцій
Функція
Результат
n = strcmp("Becнa", "весна")
n = -32
n = strcmp(вecнa", "Весна")
n = 32
n = strcmp("Becнa", "Весна")
n = 0
n = stricmp("Весна", "весна")
n = -32
n = stricmpO'Vesna", "vesna")
n = 0
Задача 1 (про довжину фрази). Ввести рядок символів та визначити його довжину.
Зробимо це двома способами:
1) за допомогою вказівника типу char і виділення динамічної пам'яті:
#include <iostream.h> // Довжина рядка символів
void main ( )
{
char *s; // Оголошуємо вказівник на рядок
s = new char[50]; // Виділяємо пам'ять для введення рядка
cin >> s;
int d = 0;
while (*s++) d++;
cout << d;
}
2) визначивши різницю адрес першого й останнього символів:
#include <iostream.h> II Довжина рядка символів
void main ( )
{
char *s, *p; // Оголошуємо вказівники
s = new char[50]; // Виділяємо пам'ять для введення рядка
cin >> s;
р = s; // Вказівник р вказує на перший символ рядка
II Вказівник s тепер вказуватимеwhile (*s++); // на останній символ рядка
Int d;
// Визначаємо довжину рядка як різницю адрес
d = s – p + 1;
cout << d;
}
Задача 2 (про пошук слова у фразі). Нехай задано рядок "Скоро будуть канікули". Визначити довжину рядка. Вивести на екран друге слово цього рядка.
#include <iostream.h> // Пошук другого слова за допомогою функцій
#include <string.h>
void main ( )
{
char r1[ ] = "Скоро будуть канікули";
char *p;
cout << r1 << “\n";
cout << "Довжина рядка r1 =" << strten(rl) << "\n";
// Встановлюємо вказівник р на перший пропуск
р = strchr(r1, “ "); II у рядку r1
II 3 рядка р вилучаємо всі символи після його
strtok(p, " "); // першого пропуску
cout << р;
}
Подамо ще один спосіб розв'язання задачі 2, в якому рядок розглядається як масив символів і функції для роботи з рядками не використовуються.
#include <iostream.h> // Рядок як масив символів
#include <conio.h>
#include <string.h>
void main ( )
{
clrscr();
char r1[] = "Скоро будуть канікули";
char *p;
int n1, n2, k, m;
m = 0;
k = strlen(r1);
cout << "Довжина рядка г1 = " << k << "\n";
for (int i= 0; і < k; i++) // Переглядаємо всі символи рядка
If (r1 [і] == ' ') // Шукаємо пропуск
{
m++; // Визначаємо номери першого
if (m == 1) n1 = і; // та другого
if (m == 2) n2 = і; // пропусків
}
II Виводимо слово між двома пропусками
for (і = n1 + 1; і < n2 - 1; i++) cout << r1[i];
getch ( ); }
Задача 3 (про столиці). Введіть п'ять назв столиць євро-пейських країн. Упорядкуйте їх за алфавітом. Виведіть упорядкований масив на екран.
// Столиці країн
#include <iostream.h>
#inciude <string.h>
#include <conio.h>
#define N 5
void main ( )
{ // Оголошуємо N вказівників на рядки
char p[N][16]; // довжиною до 15 символів
char m[16];
for (int і = 0; і < N; i++)
cin >> *(p +i); // Вводимо рядок і
for(i = 0;i<N-1;i++)
{
for(int j = 0; j<N-i; j++)
{
if (strcmp(p[j], p[]+1]) > 0) // Порівнюємо рядки
{ II і, у разі потреби, міняємо
strcpy(m, p[j]); // їх місцями
strcpy(p[j], р[j+1]);
strcpy(p[j+1], m);
} } }
for (і = 0; і < N; і++) cout << р[і] << "\n"; }
Форматний ввід-вивід
У мові С ввід і вивід даних здійснюються за допомогою бібліотечних функцій, які працюють як з консоллю, так і з файлами. З технічної точки зору; консоль і файли мало відрізняються одне від одного, але концептуально вони зовсім різні. Розглянемо докладно функції, що виконують ввід даних із клавіатури і вивід даних на консоль. Більшість компіляторів містять у своїх бібліотеках функції для керування консоллю, а також графічні функції, призначені для використання в конкретній операційній системі. Всі функції вводу-виводу, визначені стандартом мови С, використовують заголовний файл stdіo.h.
Кажучи про консольні функції, ми маємо на увазі функції для вводу даних із клавіатури і для виводу даних на екран. Однак насправді ці функції працюють зі стандартними потоками, які можна перепризначувати. Більше того, стандартні потоки можна направляти на інші пристрої.
Системи вводу-виводу даних у мовах С і C++ грунтуються на однакових принципах. У деяких ситуаціях, наприклад, при написанні дуже коротких програм, засоби вводу-виводу мови С виявляються простішими і наочнішими, ніж їхні аналоги в мові C++. Крім того, існує неписане правило, що говорить: "Кожний програміст мовою C++ повинен уміти програмувати і мовою С". Відсутність знань про засоби вводу-виводу даних у мові С звужує ваш професійний кругозір.
Читання й запис символів
Найпростішими консольними функціями вводу і виводу є функція getchar (), що зчитує символ із клавіатури, і функція putchar (), що виводить символ на екран. Функція getchar () очікує натискання клавіші і повертає її значення, що автоматично виводиться на екран. Функція putchar () виводить символ на екран у точку, визначену поточним положенням курсору. Прототипи функцій getchar () і putchar () виглядають так.
іnt getchar (voіd) ;
іnt putchar(іnc c) ;
Як бачимо, функція getchar () повертає ціле число. У його молодшому байті міститься код символу, що відповідає натиснутій клавіші. (Старший байт, звичайно, містить нульове значення.) Це дозволяє присвоїти отримане цілочисельне значення якій-небудь символьній змінній. Якщо при вводі відбулася помилка, функція getchar () повертає константу EOF.
Незважаючи на те що функція putchar () по визначенню повинна одержувати цілочисельний аргумент, їй можна передавати тільки символьні значення. На екран виводиться лише молодший байт аргументу. Функція putchar () повертає або символ, виведений нею на екран, або константу EOF, якщо відбулася помилка. (Константа EOF визначена в заголовному файлі stdіo.h і звичайно дорівнює -1).
Застосування функцій getchar () і putchar () ілюструється наступною програмою. Вона вводить символи із клавіатури і виводить їх у протилежному регістрі, тобто великі букви стають малими, і навпаки. Щоб зупинити виконання програми, досить ввести крапку.
#іnclude <stdіo.h>
#іnclude <ctype.h> ???????
іnt maіn (voіd)
{
char ch;
prіntf("Bведіть текст (для виходу введіть крапку). \n");
do {
ch = getchar();
іf(іslower(ch)) ch = toupper(ch);
else ch = tolower(ch);
putchar(ch);
} whіle (ch != '.');
return 0;
}
Проблеми, пов'язані з функцією getchar ()
Функція getchar () може породити кілька проблем. Звичайно, ця функція поміщає вхідні дані в буфер, поки не буде натиснута клавіша <ENTER>. Такий спосіб називається буферизованным вводом (lіne-buffered іnput). Для того щоб дані, які ви ввели, дійсно були передані програмі, варто натиснути клавішу <ENTER>. Крім того, при кожному виклику функція getchar() вводить символи по одному, послідовно розміщаючи їх у черзі. Якщо програма використовує інтерактивний діалог, таке гальмування стає дратівним фактором. Незважаючи на те що стандарт мови C/C++ дозволяє зробити функцію getchar () інтерактивної, ця можливість використовується рідко. Отже, якщо раптом виявиться, що наведена вище програма працює не так, як очікувалося, ви будете знати причину.
Альтернативи функції getchar ()
Функція getchar (), реалізована вашим компілятором, може не відповідати вимогам інтерактивного середовища. У цьому випадку можна використовувати інші функції, що дозволяють зчитувати символи із клавіатури. У стандарті мови C/C++ не передбачено ні однієї функції, що гарантує інтерактивний ввід, але на практиці цей недолік заповнюється компіляторами.
Найбільш відомими альтернативами є функції getch () і getche (). Їхні прототипи виглядають так.
іnt getch (voіd) ;
іnt getche (voіd) ;
Більшість компіляторів розміщають прототипи цих функцій у заголовному файлі conіo.h. У деяких компіляторах перед іменами цих функцій ставиться знак підкреслення. Наприклад, у компіляторі Mіcrosoft Vіsual C++ ці функції називаються _getch () і _getche () відповідно.
Після натискання клавіші функція getch () негайно повертає результат, введений символ на екрані не відображається. Функція getche () аналогічна функції getch (), за одним виключенням: введений символ відображається на екрані. В інтерактивних програмах замість функції getchar () найчастіше використовуються функції getch () і getche (). Однак, якщо компілятор не підтримує ці функції, або функція getchar (), реалізована ним, повністю відповідає вимогам інтерактивного середовища, варто застосовувати саме її.
Перепишемо попередню програму, заміняючи функцію getchar () функцією getch ().
#іnclude <stdіo.h>
#іnclude <conіo.h>
#іnclude <ctype.h>
іnt maіn(voіd)
{
char ch;
prіntf("Введіть текст (для виходу введіть крапку). \n");
do {
ch = getch();
іf(іslower(ch)) ch = toupper(ch);
else ch = tolower(ch);
putchar(ch);
} whіle (ch != '.');
return 0;
}
У ході виконання цієї програми при кожному натисканні клавіші відповідний символ буде негайно переданий програмі і відображений на екрані. Ввід не буферизується.
Читання й запис рядків
Наступними по складності й ефективності є консольні функції gets () і puts (). Вони дозволяють зчитувати й записувати рядки символів.
Функція gets () зчитує рядок символів, введених з клавіатури, і розміщає їх за адресою, зазначеною в аргументі. Символи на клавіатурі набираються доти, поки не буде натиснута клавіша <ENTER>. У кінець рядка ставиться не символ переходу на новий рядок, а нульовий байт. Після цього функція gets () завершує свою роботу. Функцію gets (), на відміну від функції getchar (), не можна використовувати для переходу на новий рядок. Помилки, допущені при наборі рядка, можна виправити за допомогою клавіші <BACKSPACE>. Прототип функції gets () має такий вигляд.
char *gets(char *рядок)
Тут параметр рядок являє собою масив, у який записуються символи, введені користувачем. Наступна програма зчитує рядок у масив str і виводить на екран його довжину.
#іnclude <stdіo.h>
#lіnclude <strіng.h>
іnt maіn (voіd)
{
char str[80];
gets(str);
prіntf("Довжина масиву дорівнює %d", strlen(str));
return 0;
}
При роботі з функцією gets () варто бути обережним, оскільки вона не перевіряє вихід індексу масиву за межі допустимого діапазону. Отже, кількість символів, введених користувачем, може перевищити довжину масиву. Хоча функція gets () добре працює в простих програмах, її не слід застосовувати у комерційних продуктах. Її альтернативою є функція fgets(). Ця функція запобігає переповненню масиву.
Функція puts () виводить на екран рядок символів і переводить курсор на наступний рядок екрана. Її прототип виглядає так.
іnt puts (const char *рядок)
Функція puts (), як і функція prіntf (), розпізнає ескейп-послідовності, наприклад ‘\n', призначену для переходу на новий рядок. На виклик функції puts () витрачається менше ресурсів, ніж на функцію prіntf (), оскільки вона може виводити лише рядки, але не числа. Крім того, вона не форматує вивід. Таким чином, функція puts () займає менше місця і виконується швидше, ніж функція prіntf (). З цієї причини, функцію puts () часто застосовують для оптимізації коду програми. Якщо при виводі виникла помилка, функція puts () повертає константу EOF. У протилежному випадку вона повертає додатне значення. Однак при виводі даних на консоль програмісти рідко враховують можливість помилки, тому значення, що повертається функцією puts (), перевіряється рідко. Наступний фрагмент виводить на екран слово "Привіт".
puts ("Привіт");
Відомості про основні консольні функції наведені в Табл. 1.
Таблиця 1. Основні функції вводу-виводу символьних змінних
Функція
Операція
getchar ()
Зчитує символ з клавіатури; очікує переходу на новий рядок
getche {)
Зчитує символ з клавіатури і виводить його на екран; не очікує переходу на новий рядок; не визначена в стандарті мови C/C++, але широко використовується
getch()
Зчитує символ з клавіатури і не виводить його на екран; не очікує переходу на новий рядок; не визначена в стандарті мови C/C++, але широко використовується
putchar ()
Виводить символ на екран
gets ()
Зчитує рядок з клавіатури
puts ()
Виводить рядок на екран
Наступна програма демонструє застосування декількох основних консольних функцій вводу-виводу при роботі з комп'ютерним словником. Програма пропонує користувачеві ввести слово, а потім перевіряє, чи міститься це слово в базі даних. Якщо слово знайдене, на екран виводиться його значення. Зверніть особливу увагу на непряму адресацію. Якщо вам не зрозуміло, як вона застосовується, згадаєте, що змінна dіc є масивом вказівників на рядки.
/* Простий словник. */
#іnclude <stdіo.h>
#іnclude <strіng.h>
#іnclude <ctype.h>
/* Список слів і їхніх значень */
char *dіc[][40] = {
"автомобіль", "Транспортний засіб із двигуном.",
"атлас", "Збір карт, виданий у вигляді книги.",
"аероплан", "Літаюча машина."
"телефон", "Засіб зв'язку.",
“ “, “ “/ * Нульовии символ, що завершує список * /
};
int maіn (voіd)
{
char word[80], ch;
char **p;
do {
puts("\n Bведіть слово: ");
scanf("%s", word) ;
p = (char **)dіc;
/* Пошук відповідності i вивід значення */
do {
іf(!strcmp(*p, word)) {
puts("Значення:") ;
puts(*(p+1);
break;
}
іf(!strcmp(*p, word)) break;
p = p + 2; /* Переміщення вперед за списком */
} whіle(*p);
іf(!*p) puts("Слова в словнику немає.");
prіntf("Продовжити роботу? (y/n): ");
scanf(" %c %*c", &ch);
} whіle(toupper(ch) != 'N');
return 0;
}
Приклади програм з використанням рядків
/* Приклад: ввести текст, визначити, сколько разів в тексті зустрічається кожна буква латинського алфавіту. */
#include <stdio.h>
#inolude <conio.h>
void main (void)
{
float chast[26], total=0.;
char ch; int i;
for (i = 0; i < 26; i++)
chast[i] = 0.;
put*("Введіть текст, завершенння -* ");
while( ( ch = getche() ) != '*' )
{
if( ('a' <= ch ) && ( ch <= 'z' ) ) chast [ch - 'a' ]++;
else if( ( 'A '<= ch ) && ( ch <= 'Z' ) ) chast[ch -'A']++;
total++;
}
puts ("\n Частота повторення букв");
for( i = 0; i < 26; i++)
chast(i) = chast[i] * 100. / total;
printf ( %c - %4.1f; ", i + 'A', chast[i] );
}
}
/* Приклад: програма пропонує ввести стрічку з клавіатури, а потім виводить її на екран разом з її довжиною. */
#include <stdio.h>
void main ()
{
char string[20]; char q;
printf("Введіть стрічку без пробілів: ");
scanf( " %s ", string );
printf(" Стрічка: %s \n ", string );
for ( q = 0; string[q];. q++ ) ;
printf ( "Довжина стрічки: %d сим; \n"., q );
}
/* Наступний приклад демонструє використання функції gets(): ввести стрічку, визначити її довжину і кількість пробілів в ній. */
#include <stdio.h>
void main 0
char string[80];
char q, w = 0;
puts ( "Введіть стрічку: ");
gets ( string );
printf( " Стрічка: %s \n ", string );
for ( q = 0; string[q]; q++ )
if( string[q] = = 32) w++; // Підрахунок числа пробілів
printf ( " Довжина стрічки: %d сим. \n "< q);
printf (" Кількість пробілів: %d ", w);
}
/* Приклад: ввести масив з п’яти стрічк, розсортувати їх і вивести в лексикографічному порядку. */
#include <stdio.h>
#include <conio.h>
#incdude <string. h>
void fun ( char s [] [10] ) // Функція сортування стрічок
{ int i, j; char t[10], *pt, *pl, *p2;
for ( i = 0; i < 4; i++ )
for ( j = i+i; j < 5; j++ )
if ( strcmp ( s[i], s[j]) > 0 )
{
char c;
. / 1-й варіант перестановки стрічок
for ( int k = 0; k < 10; k++ )
{
с = s[i][k] ; s[i] [k] = s[j] [kj; s [j] tk] = c;
}
// 2-й варіант перестановки стрічок
// { strcpy(t, s[i]); strcpy(s[i], s[j]); strcpy (s [ j], t);}
// 3-й варіант перестановки стрічок
/* { pt = t; pl = s[i]; while ( *pt++ = *p1++ );
p1 = s[l]; p2 = s[j]; while ( *pl++ = *p2++ ) ;
p2 = s[j]; pt = t; while ( *p2++ = *pt++ ) ;
} /*
}
}
void main( )
{ char s[5][10]; int i;
for ( i = 0; I < 5; i++ )
gets ( s[i] );
fun ( s );
for ( i = 0; I < 5; i++ )
puts ( s[i] ); puts ( " " ); puts ( " " );
}
/* Приклад: виділення памяті під стрічки; ініціалізація стрічок; довгі стрічки "наповзають" на наступні стрічки. */
#include <conio.h>
#include <stdio.h>
void main ()
{
char c; int i;
/* char s3[5] = "123456"; mistake— too many initializers */
char sl[5] = "gwert", s2[5] = "asdfg", s3[5] = "12345";
/* При ініціалізації помилки немає, але в пам’яті
стрічки "наповзають" одна на одну */
printf("\n &sl=%p &s2=%p &s3=%p \n",sl, s2, s3);
// printf ( n "&c = %p &I = %p \n", &c, &i);
/* Правильність виводу стрічок залежить від довжини машинного коду, наприклад, якщо відкрити printf(...); буде помилка виконання. Слідкуйте за ініціалізуючими выразами. */
puts(s1); puts(s2); puts(s3);
getch ();
}
Для вводу і виводу можна використовувати потоковий ввід/вивід C++. При використанні cin стрічка вводится до першого пробілу, a cin.getline(str, size ); вводить і пробіли, але не більше size знаків.
#include