Як записувати рядок у Сі




Як записувати рядок у Сі



Рядки в Сі. Основні функції.

Рядок це набір символів char, що завершуються нульовим символом закінчення рядка '\0' або 0.

char *name = "Victor"; // Нульовий символ буде вставлено після останньої літери r char name[] = "Victor"; char name[7] = "Victor"; // Необхідно резервувати місце під символ закінчення рядка char name[7] = "Victor\0"; // Рядок з явною вказівкою завершення

Функції роботи з рядками

atof() Перетворює рядок у float.
atoi() Перетворює рядок на int.
atoll() Перетворює рядок у long long.
fgets() Читає рядки з файлу або клавіатури.
gets() Читає рядки з клавіатури.
memccpy() Копіює задану кількість байт або до першого знаходження заданого символу (включаючи його).
memcpy() Копіює задану кількість байт (символів) з src в dst.
memmove() Копіює задану кількість байт (символів) з src в dst.
printf() Виводить текст на екран.
scanf() Перетворює введення з клавіатури на змінні (рядкові, числові і т.д.), відповідно до специфікатора формату.
sprintf_s() Перетворює рядок на тип відповідно до специфікатора формату.
strchr() Шукає символ у рядку і повертає на нього покажчик, якщо не знайдено - NULL.
strcpy() Копіює рядок (включаючи нульовий символ, що завершує рядок) в інший рядок.
strncpy() Копіює рядок (включаючи завершальний рядок нульовий символ) в інший рядок з обмеженням довжини рядка, що копіюється.
strlen() Повертає довжину рядка без кінцевого нульового символу.
strtod() Перетворює рядок у double.
strcat() Здійснює об'єднання двох рядків.
strncat() Здійснює об'єднання двох рядків з обмеженням довжини рядка, що додається.
strdup() Виділяє пам'ять та копіює рядок, повертає адресу скопійованого рядка.

Сподобалася сторінка?
Додати до закладок
Або поділитись!

Введення та виведення символьних рядків у Сі

Отже, рядки у мові Сі. Для них не передбачено окремого типу даних, як це зроблено у багатьох інших мовах програмування. У мові Сі рядок – це масив символів. Для позначення кінця рядка використовується символ '\0' , про який ми говорили в минулій частині цього уроку. На екрані він ніяк не з'являється, тому подивитися на нього не вийде.

Створення та ініціалізація рядка

Оскільки рядок – це масив символів, то оголошення та ініціалізація рядка аналогічні подібним операціям з одновимірними масивами.

Наступний код ілюструє різні способи ініціалізації рядків.

char str [10]; char str1[10] =; char str2[10] = "Hello!"; char str3[] = "Hello!";

Рис.1 Оголошення та ініціалізація рядків

У першому рядку ми просто оголошуємо масив із десяти символів. Це не зовсім рядок, т.к. в ній відсутній нуль-символ \0, поки це просто набір символів.

Другий рядок. Найпростіший спосіб ініціалізації у лоб. Оголошуємо кожен символ окремо. Тут головне не забути додати нуль-символ \0.

Третій рядок – аналог другого рядка. Зверніть увагу на картинку. Т.к. символів у рядку праворуч менше, ніж елементів у масиві, решта елементів заповниться \0 .

Четвертий рядок. Як бачите, тут не встановлено розміру. Програма його обчислить автоматично та створить масив символів необхідної довжини. При цьому останнім буде вставлено нуль-символ 0 .

Як вивести рядок

Доповнимо код вище до повноцінної програми, яка виводитиме створені рядки на екран.

#include int main(void) < char str[10]; char str1[10] =; char str2[10] = "Hello!"; char str3[] = "Hello!"; for(int i = 0; i

Рис.2 Різні способи виведення рядка на екран

Як бачите, є кілька основних способів вивести рядок на екран.

  • використовувати функцію printf зі специфікатором %s
  • використовувати функцію puts
  • використовувати функцію fputs, вказавши як другий параметр стандартний потік для виведення stdout.

Єдиний нюанс у функцій puts та fputs. Зверніть увагу, що функція puts переносить виведення на наступний рядок, а функція fputs не переносить.

Як бачите, з висновком все досить просто.

Введення рядків

З введенням рядків все трохи складніше, ніж із виводом. Найпростішим способом буде наступне:

#include int main(void)

Функція gets припиняє роботу програми, читає рядок символів, введених з клавіатури, і поміщає символьний масив, ім'я якого передається функції як параметр.
Завершенням роботи функції gets буде символ, відповідний клавіші введення та записуваний у рядок як нульовий символ.
Помітили небезпеку? Якщо ні, то вас люб'язно попередить компілятор. Справа в тому, що функція gets завершує роботу лише тоді, коли користувач натискає клавішу введення. Це може призвести до того, що ми можемо вийти за рамки масиву, в нашому випадку — якщо введено більше 20 символів.
До речі, раніше помилки переповнення буфера вважалися найпоширенішим типом уразливості. Вони зустрічаються і зараз, але використовувати їх для злому програм стало набагато складніше.

Отже, що ми маємо. Ми маємо завдання: записати рядок у масив обмеженого розміру. Тобто ми повинні якось контролювати кількість символів, які користувач вводить. І тут нам на допомогу приходить функція fgets:

#include int main(void)

Функція fgets приймає на вхід три аргументи: змінну для запису рядка, розмір рядка, що записується, і ім'я потоку, звідки взяти дані для запису в рядок, в даному випадку — stdin . Як ви вже знаєте з трьох уроків, stdin – це стандартний потік введення даних, зазвичай пов'язаний з клавіатурою.Зовсім необов'язково дані повинні надходити саме з потоку stdin, надалі цю функцію ми також використовуватимемо для читання даних із файлів.

Якщо в ході виконання цієї програми ми введемо рядок довше, ніж 10 символів, масив все одно буде записано лише 9 символів з початку і символ перенесення рядка, fgets «обріже» рядок під необхідну довжину.

Зверніть увагу, що функція fgets зчитує не 10 символів, а 9 ! Як ми пам'ятаємо, у рядках останній символ зарезервовано для нуль-символу.

Давайте це перевіримо. Запустимо програму з останнього лістингу. І введемо рядок 1234567890. На екран виведеться рядок 123456789.

Рис.3 Приклад роботи функції fgets

Виникає питання. А куди подівся десятий символ? А я відповім. Він нікуди не подівся, він залишився в потоці введення. Виконайте наведену нижче програму.

#include int main(void)

Ось результат роботи.

Рис.4 Непорожній буфер stdin

Поясню те, що сталося. Ми викликали функцію fgets. Вона відкрила потік введення та дочекалася доки ми введемо дані. Ми ввели з клавіатури 1234567890 (n я позначаю натискання клавіша Enter ). Це вирушило в потік введення stdin. Функція fgets, як і належить, взяла з потоку введення перші 9 символів 123456789, додала до них нуль-символ \0 і записала це в рядок str. У потоці введення залишилося ще 0\n.

Далі ми оголошуємо змінну h. Виводимо її значення на екран. Після чого викликаємо функцію scanf. Тут очікується, що ми можемо щось запровадити, але т.к. в потоці введення висить 0\n , то функція scanf сприймає це як наше введення, і записується 0 змінну h . Далі ми виводимо її на екран.

Це, звичайно, не зовсім така поведінка, яку ми очікуємо. Щоб впоратися з цією проблемою, необхідно очистити буфер введення після того, як ми вважали рядок, введений користувачем.Для цього використовується спеціальна функція fflush. Вона має лише один параметр – потік, який потрібно очистити.

Виправимо останній приклад так, щоб його робота була передбачуваною.

#include int main(void) < char str[10]; fgets(str, 10, stdin); fflush(stdin); // Очищаємо потік введення puts (str); int h = 99; printf("do %d\n", h); scanf("%d",&h); printf("posle %d\n", h); return 0; >

Тепер програма працюватиме так, як треба.

Рис.4 Скидання буфера stdin функцією fflush

Підсумовуючи, можна відзначити два факти. Перший. На даний момент використання функції gets є небезпечним, тому рекомендується скрізь використовувати функцію fgets.

Другий. Не забувайте очищати буфер введення, якщо використовуєте функцію fgets.

На цьому розмова про введення рядків закінчена. Ідемо далі.

Збережи в закладки або підтримуй проект.

Практика

Розв'яжіть запропоновані завдання:

Для зручності роботи відразу переходьте в повноекранний режим

Дослідницькі завдання для хакерів

  1. Перевірте як поводиться компілятор у разі переповнення буфера.

Додаткові матеріали

Запис та зчитування символів та рядків. Частина 1

Доброго часу доби! Сьогодні ми поговоримо про рядки та символи в Сі, і про те, як вони передаються у файл.

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

Режими читання та запису файлів

У Сі, для відкриття файлу, використовується команда fopen(), в аргументах якого записується ім'я файлу та позначення режиму запису:

r (r+) - файл відкривається для читання (читання та запису);

w (w+) — відкривається порожній файл для запису (читання та запису). Якщо файл з такою назвою існує, він стирається;

a (а+) — файл відкривається для доповнення до кінця (читання та доповнення).

Як приклад: file = fopen("file.tx) .

Специфікатори

Повторимо основну частину функції scanf():
%c Читає одиночні символи
%d Читає десяткове число
%f Читає число з плаваючою комою
%s Читає рядок

Інші функції зчитування розберемо на прикладах.

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

Тепер, коли ми все узагальнили, приступимо до завдань на символи та рядки.

Записати в текстовий файл на різних рядках 5 слів та 3 числа, закрити його, а потім дописати туди ще 2 символи.

Це нескладне завдання перевіряє нас на знання тих самих режимів відкриття файлів, про які ми говорили раніше.

#include
#include
int
main(void)

FILE*file; file =
fopen(«file.txt»,»w+»);
char str[200];
int ch1, ch2, ch3;
gets(str);
scanf(«%d%d%,
& ch1,& ch2,& ch3);

Для роботи з рядками Сі передбачені різноманітні бібліотеки з різними функціями. У стандартній бібліотеці список таких функцій скромний, але в більшості випадків цього достатньо. gets() аналог функції scanf(), однак, працює він лише з рядком. Записує в зазначений аргумент рядок, що сканується ним, з консолі введення у форматі символів.

Насправді, і звичайні рядки слід сприймати як звичайні одновимірні масиви з форматом char. Також слід врахувати, що розмір масиву (у нас char str[200]) має бути не менше ніж рядок, а краще більше.

fputs(str, file);
fprintf(file,"\n%d,
%d,
%d", ch1,ch2,ch3);
fclose(file);

Зроблено запис у файл зчитаних з консолі рядка та цифр. І закрили файл. ЗАВЖДИ Закрийте файл після відкриття. інакше це може вплинути на працездатність комп'ютера.

file =
fopen("file.txt","a+");
char sym1 =
'R', sym2 =
'T';
fprintf(file,
"
\n
%c
,
%c
", sym1, sym2);
fclose(file);
return EXIT_SUCCESS;
>

Йдемо за завданням і знову відкриваємо файл. Звертаю увагу до режиму відкриття файлу («a+»), записуємо туди 2 символи. І закриваємо файл.

Створити вручну текстовий файл англомовного невеликого обсягу.Прочитати файл символом і вивести на екран усі символи з файлу. Пропустивши рядок, вивести на екран першу та останню літеру кожного рядка у файлі.

Так як має бути складніша робота з рядками, відразу підключимо бібліотеку string.h

#include
stdio.h>
#include
stdlib.h>
#include
string.h>
#define
N 200
int
main(void)

int i =
0;
FILE*file; file =
fopen("file.txt",
"r");
char sym[N], c =
0;
while(
(c =
fgetc(file))
!=
EOF)
printf("%c", c);
>

Після відкриття файлу в режимі читання та ініціалізації змінних, йде код, який стане вам у нагоді в майбутньому. Виведення на екран файлу символічно! В умовах while вказано «поки сканований символ не означає кінець файлу». EOF - символ відомий в С++ як \0, означає кінець файлу.

fclose(file);
printf("\n"); file =
fopen("file.txt",
"r");
while(
!feof(file))
fscanf(file,"%s",sym); i =
(strlen(sym));
printf("%c
%c
", sym[0], sym[i-1]);
>
fclose(file);
return EXIT_SUCCESS;
>

Умова, що використовується при while, так само як і в попередній статті, однак має більш коротку форму. Функція strlen() з бібліотеки string.h дозволяє визначити довжину рядка. І уявивши, що рядок — одномірний масив, звернемося до конкретних символів через індекс.

Створити вручну текстовий файл англомовного невеликого обсягу. Знайти, скільки всього голосних міститься у цьому файлі. Знайти кількість голосних у кожному рядку файлу. Результати дописати цей же файл на новому рядку.

#include
stdio.h>
#include
stdlib.h>
#include
string.h>
#define
N 100
int
main(void)

int vse =
0, i =
0, k =
0;
FILE*file; file =
fopen("file.txt",
"r");
char c =
0, temp[N];
while(
(c =
fgetc(file))
!=
EOF)
if
((c ==
'A')
||
(c ==
'a')
||
(c ==
'E')
||
(c ==
'e')
||
(c ==
'I')
||
(c ==
'i')
||
(c ==
'O')
||
(c ==
'o')
||
(c==
'Q')
||
(c ==
'q')
||
(c ==
'U')
||
(c ==
'u')
||
(c ==
'Y')
||
(c ==
'y')) vse++;
>
fclose(file);

Насамперед, порахуємо кількість голосних у всьому файлі за допомогою лічильника vse.

file =
fopen("file.txt",
"r"); k =
0;
while
(!feof(file))
fgets(temp, N, file); k++;
>
fclose(file);

Тепер порахуємо кількість рядків, щоб створити одномірний масив з кількістю елементів, що дорівнює кількості рядків.

file  =
fopen("file.txt",
"r");
int
* kol;
int j; kol  =
(int*)malloc(k  *
sizeof(int));
for
(j  =
0; j   k; j++) kol[j]
=
0;
fgets(temp, N  ,file);
for
(i  =
0; i  
(strlen(temp)); i++)
if
((temp[i]
==
'A')
||
(temp[i]
==
'a')
||
(temp[i]
==
'E')
||
(temp[i]
==
'e')
||
(temp[i]
==
'I')
||
(temp[i]
==
'i')
||
(temp[i]
==
'O')
||
(temp[i]
==
'o')
||
(temp[i]
==
'Q')
||
(temp[i]
==
'q')
||
(temp[i]
==
'U')
||
(temp[i]
==
'u')
||
(temp[i]
==
'Y')
||
(temp[i]
==
'y')) kol[j]++;
>
>
fclose(file);

Не лякайтесь, друзі! Для створення масиву, розмір якого міститься у змінній, використовується команда (int *) malloc (k * sizeof (int)); . Грубо кажучи, ми створили динамічний масив у Сі. У циклі, скануючи по рядку за допомогою fgets() (де temp - Змінна куди записати рядок, N - Кількість символів, file - Назва файлу з яким працюємо), знаходимо в рядку голосні літери. Наприкінці записуємо значення лічильника до нашого масиву.

file  =
fopen("file.txt",
"a+");
fprintf(file,"\n");
for
(j  =
0; j   k; j++)
fprintf(file,"%d
", kol[j]);
>
fprintf(file,"\t
vse
%d", vse);
fclose(file);
free(kol);
return EXIT_SUCCESS;
>

Тепер просто записуємо показання лічильників, що потрібні за завданням, в кінець файлу. Як і у разі закриття файлів, так і при роботі з malloc ЗАВЖДИ звільняйте пам'ять наприкінці програми за допомогою команди free() , де в аргументах ім'я змінної.

На сьогодні все, якщо лишилися питання, пишіть у коментарях. Ось вихідники:

Усі вихідні коди без файлів txt.
Завантажити вихідні завдання — 1
Завантажити вихідні завдання — 2
Завантажити вихідні завдання — 3

Подiлитись посиланням:

Схожі статті

  • Як вимкнути захист у реальному часі Windows 10 через командний рядок
  • Як перейти на наступний рядок без введення
  • Як зі стовпця зробити рядок в excel через кому
  • Як зробити відновлення системи Windows 10 через командний рядок
  • Чи потрібно записуватись до нарколога
  • Як прочитати один рядок з файлу з
  • Як перейти на новий рядок клавішами
  • Як увімкнути безпечний режим Windows 11 через командний рядок
  • Недавні статті

  • Як бродить зернова брага
  • Що робити якщо не засмагаєш на сонці чому засмага погано лягає на шкіру або перестає прилипати
  • Як швидко зняти гель лак без апарату
  • Як робиться Каті голови
  • Яка гребінець краще для об'єму
  • Чим роблять м'яку покрівлю
  • Чи можна залишати крем для обличчя на ніч
  • Де знаходиться датчик селектора
  • географія нашої діяльності
    вулиця Драгоманова, 27
    вул. Курчатова 1Б
    вул. Міцкевича 130
    вул. Лабунського, 1
    вул. Макарова-Пржевальського
    вул. Толстого 10
    вул. Грушевського 28
    вул. Перший промінь (Черняхівського)
    напишіть нам

    сообщение успешно отправлено
    x