#Комп’ютерний практикум № 8

#ТЕКСТОВІ ФАЙЛИ

Мета роботи - вивчити особливості створення і обробки текстових файлів даних.

##Теоретичні відомості

Текстовий файл є сукупністю символьних рядків змінної довжини. Кінець кожного рядка у такому файлі позначається спеціальним маркером кінця рядка Eoln, що представляє собою пару керуючих символів: "переведення каретки" (#13) і "переведення рядка" (#10). Наприкінці файла записується маркер кінця файла — керуючий символ з кодом #26.
Текстові файли є файлами тільки послідовного доступу.

У С-програмах текстовий файл оголошують як змінну-покажчик стандартного типу FILE: FILE *покажчик
Структура типу FILE містить різноманітні відомості про файл: його ім'я, розташування на диску, режим роботи з файлом, покажчик поточної позиції і т. ін. Вона оголошена в стандартоному заголовному файлі stdio.h.
Відповідність між іменем фізичного файла і покажчиком на файл у програмі встановлюється при відкритті файлу. При відкритті файлу також встановлюється і режим його обробки.
Відкриття файлу засобами С здійснюється за допомогою функції fopen_s.
Синтаксис:

   FILE** pFile,
   const char *filename,
   const char *mode 
);```  

Параметри:  
**pFile** - покажчик на файловий покажчик, котрий отримує покажчик на відкритий файл;  
**filename** - ім’я файлу, який відкривається;  
**mode** - режим доступу до файлу, рядок символів, що визначає потрібний статус (режим) відкриття файлу.  
Допустимі значення режимів доступу наведено у таблиці 1.  

Таблиця 1. Допустимі значення режимів доступу

| Режим   |      Призначення      |
|----------|:-------------:|
|Визначення довжини рядка| |
| r |  відкрити існуючий файл тільки для читання |
| w |  створити новий файл тільки для запису (якщо відповідний фізичний файл існує, то його вміст втрачається) |
| a |  відкрити існуючий файл для дозапису в кінець файлу або створити новий файл, якщо такого не існує |
| r+ |  відкрити існуючий файл для читання і запису |
| w+ |  створити новий файл для читання і запису (якщо відповідний фізичний файл існує, то його вміст втрачається) |
| a+ |  відкрити існуючий файл в режимі читання і дозапису в кінець файлу або створити новий файл, якщо такого не існує |

Ознакою відкриття саме текстового файла є додавання до рядка, що визначає режим доступу до файла, суфікса **t**. Символ **«+»** означає відкриття файла і для читання, і для запису.  
Порядок букв в рядку режиму наступний: спочатку йде одна з букв **"r"**, **"w"**, **"a"**, потім в довільному порядку можуть йти символи **"t"** та **"+"**. Тобто, рядки, подібні **"r+t"** можуть бути представлені і у вигляді **"rt+"**.  
У разі вдалого відкриття файлу функція `fopen_s` повертає 0, інакше відповідний код помилки.  
Для читання-запису текстових файлів використовують, в основному, функції рядкового та символьного введення-виведення (таблиця 2).  

Таблиця 2. Функції рядкового та символьного введення-виведення  

| Функція   |      Опис      |
|----------|:-------------:|
| `char *fgets(char *str, int n, FILE *stream);` | читання n символів із файла stream в рядок, на який вказує покажчик str  (з додаванням ’\0’) |
| `int fputs( const char *str, FILE *stream );` | запис у файл stream рядка, на який вказує покажчик str |
| `int fgetc(FILE *stream );` | читання символа із файла stream |
| `int fputc(int c, FILE *stream);` | запис символа c в файл stream |

Якщо рядок (символ) не може бути прочитаний (записаний), то повертається макрос `EOF` (стандартне значення, яке повертається тоді, коли функція введення намагається виконати читання після кінця файлу).  
У файлах, відкритих для читання і запису, потік повинен бути обнулений (очищений) після запису, перш ніж виконувати операції читання. Це може бути зроблено шляхом виклику функції `fflush()`, яка примусово записує дані з буфера у файл незалежно від ступеня заповнення буфера.  
В текстові файли, загалом, можна також вводити і несимвольні дані, зокрема, числові. При записі в текстовий файл такі дані перетворюються із внутрішньої форми подання в символьну і зберігаються в символьному вигляді; при читанні виконується зворотне перетворення.    
Відповідні дії по читанні/запису нетекстової інформації можна виконати за допомогою функцій форматованого введення-виведення (таблиця 3).  

Таблиця 3. Функції форматованого введення-виведення  

| Функція   |      Опис      |
|----------|:-------------:|
| `int fscanf_s(FILE *stream, const char *format [,argument ]...);` | зчитування даних iз файла stream по формату format в аргументи [,argument ] |
| `int fprintf_s(FILE *stream, const char *format [,argument ]...);` | запис у файл stream по формату format списку аргументів [,argument ]|

Як результат, у всіх цих функцій, повертається кількість зчитаних (записаних) елементів або 0. У разі винекнення помилки, буде повернуто від'ємне значення. 
При виконанні кожної операції введення/виведення покажчик поточної позиції файлу зміщується на одну позицію в сторону кінця файлу. В якийсь момент він досягає кінця файлу. Для перевірки цього факту використовується функція feof():`feof(покажчик)`.  
Ця функція повертає значення, відмінне від нуля (true), якщо всі елементи файлу прочитані і покажчик файлу вказує на маркер кінця файлу (знаходиться за останнім елементом файлу) або файл після відкриття виявився порожнім; у всіх інших випадках функція повертає значення false (0). Використовуючи функцію feof() у циклі з передумовою, можна читати вміст файлу, поки не буде до-сягнутий його кінець:  
```while  (! feof(f)) 
{ … 
}	```  
##	Вимоги до програми  
1.	Виведення вхідних, проміжкових і вихідних даних.
2. Створення файла програмним шляхом.
3.	Організація введення інформації аналогічно текстовим редакторам (ознака кінця рядка – натиснення Enter, ознака кінця введення файла – будь-яка комбінація клавіш або клавіша, що генерують розширений код).
4.	Можливість доповнення файла.

##	Варіанти завдань
1. 	Створити текстовий файл. Знайти найдовші слова в кожному його рядку та переписати їх в новий текстовий файл. Записати останнім рядком нового файлу загальну кількість слів у вихідному файлі. Вивести вміст вихідного і створеного файлів.
2. 	Створити текстовий файл, деякі рядки якого починаються із символа '#'. Сформувати новий текстовий файл, скопіювавши до нього вміст вихідного файлу таким чином, щоб рядки вихідного файлу, які починаються із символу '#', були переставлені в кінець файлу з видаленням самого символу '#' і додаванням у середину такого рядка символу '!'. Вивести вміст вихідного і створеного файлів.
3. 	Створити текстовий файл. Слова у файлі відділені пробілами, комами, крапками. У кожному реченні визначити саме довге слово. Створити новий те-кстовий файл, у якому кожне речення розміщується у окремому рядку і почи-нається із числа, що дорівнює довжині самого довгого слова в ньому, за яким йде саме це слово. Вивести вміст вихідного і створеного файлів.
4. 	Створити текстовий файл. Сформувати новий текстовий файл, що склада-ється з рядків вхідного файлу, у яких вилучені всі односимвольні слова, а також зайві роздільники (пробіли, коми, крапки), що повторюються підряд. Визначити і дописати в кінець нового файлу кількість вилучених слів і зайвих символів кожного виду. Вивести вміст вихідного і створеного файлів.
5. 	Створити текстовий файл. Кожен парний рядок вихідного файлу перепи-сати в перший новий текстовий файл, кожен непарний - у другий. У файлі з па-рними рядками лексично впорядкувати рядки за алфавітом. У файлі з непарними рядками впорядкувати слова в кожному із перших N рядків. Вивести вміст вихідного і створеного файлів.
6. 	Створити текстовий файл, рядки якого містять розділені пробілами слова, що складаються із цифр або символів. В кожному рядку, що містить числа, знайти найбільше із них. Переписати такі рядки (що містять числа) у новий те-кстовий файл наступним чином: починається такий рядок знайденим найбільшим числовим значенням, далі послідовно записуються тільки числові значення відповідного рядка вихідного файлу, розділені комами. Вивести вміст вихідного і створеного файлів.
7. 	Створити текстовий файл. Сформувати новий текстовий файл, що склада-ється зі слів вхідного файлу, які зустрічаються у ньому більше N раз. Розмістити ці слова в новому файлі в порядку зростання їхньої довжини. Вивести вміст вихідного і створеного файлів.
8. 	Створити два текстових файли. Переписати в новий текстовий файл рядки, які є у другому вихідному файлі, і відсутні у першому. Визначити кількість таких рядків. Вивести вміст вихідного і створеного файлів.
9. 	Створити текстовий файл. Сформувати новий текстовий файл, що склада-ється з рядків вихідного файлу, розміщених у порядку зростання кількості сим-волів у них. Наприкінці кожного рядка нового файлу дописати кількість символів у рядку. Вивести вміст вихідного і створеного файлів.
10. 	Створити текстовий файл. В кожному непарному рядку визначити кіль-кість цифрових символів і записати цю величину останнім елементом рядка. Вивести вміст вихідного і перетвореного файлів.
11. 	Створити текстовий файл. Визначити в кожному його рядку кількість слів і довжину найбільшого слова. Дописати значення кількості слів на початок від-повідного рядка, довжину максимального слова - в його кінець. Вивести вміст вхідного і перетвореного файлів.
12. 	Створити текстовий файл. Визначити в кожному його рядку слова, які починаються на задану літеру. Зберегти знайдені слова у новому текстовому файлі. Як роздільники між словами застосовувати пробіли.
13. 	Створити текстовий файл. Сформувати новий текстовий файл, що склада-ється з рядків вихідного файлу, у яких вилучені всі двосимвольні слова. Визна-чити і дописати в кінець нового файлу кількість вилучених слів. Вивести вміст вихідного і створеного файлів.
14. 	Створити текстовий файл. Сформувати новий текстовий файл, що склада-ється з рядків вихідного файлу, у яких вилучені початкові та кінцеві пробіли і подвоєні проміжні. Визначити і дописати в кінець кожного рядка нового файла кількість доданих у нього пробілів. Вивести вміст вихідного і створеного файлів.
15. 	Створити текстовий файл. Переписати його компоненти до нового текс-тового файлу, вставляючи в кінець кожного рядка літеру, що є останньою в першому слові рядка. Вивести вміст вихідного і створеного файлів.
16. 	Створити текстовий файл. Переписати його компоненти до нового текс-тового файлу, вставляючи на початку кожного рядка поточну довжину рядка у вихідному файлі. Вивести вміст вихідного і створеного файлів.
17. 	Створити текстовий файл. Переписати його компоненти до нового текс-тового файлу, вставляючи на початку рядка порядковий номер, в кінці рядка -поточну довжину рядка у вихідному файлі. Вивести вміст вихідного і створеного файлів.
18. 	Створити текстовий файл. Переписати до нового текстового файлу всі компоненти вихідного файлу, замінивши в них символ 0 на 1 і навпаки. Вивести вміст вихідного і створеного файлів.
19. 	Створити текстовий файл. Переписати його вміст у новий текстовий файл, замінюючи кожен рядок символом '-', якщо він у вихідному файлі закінчується на літеру, відмінну від символа пропуску, коми або крапки. Вивести вміст вихід-ного і створеного файлів.
20. 	Створити текстовий файл. Переписати його компоненти до нового текс-тового файлу, вставляючи на початок кожного рядка літеру, що є першою в останньому слові рядка. Вивести вміст вихідного і створеного файлів.
21. 	Створити два текстових файли. Переписати в новий текстовий файл рядки, які є в обох вихідних файлах. Визначити кількість таких рядків. Вивести вміст вихідних і створеного файлів.
22. 	Створити текстовий файл. Слова у файлі відділені пробілами, символами "," та ";". Переписати в новий текстовий файл рядки вихідного файлу, вставляючи на початок кожного рядка число, що дорівнює кількості однакових слів у цьому рядку. Вивести вміст вихідного і створеного файлів.
23. 	Створити текстовий файл. Переписати його вміст у новий текстовий файл, переформатувавши рядки вихідного файлу на задану користувачем довжину шляхом рівномірної вставки пробілів між словами. Вивести вміст вихідного і створеного файлів.
24. 	Створити текстовий файл. Скопіювати останні N рядків вихідного файлу до нового текстового файлу. У новому файлі знайти повторювані рядки і вида-лити їх. Визначити кількість видалених рядків. Вивести вміст вихідного і ство-реного файлів.
25. 	Створити два текстових файли. Переписати в новий текстовий файл рядки, які є в першому вихідному файлі, і відсутні у другому. Визначити кількість таких рядків. Вивести вміст вихідних і створеного файлів.
26. 	Створити текстовий файл. Слова у файлі відділені комами, крапкою з ко-мою, пробілами, крапками. У кожному реченні визначити саме коротке слово. Створити новий текстовий файл, у якому кожне речення розміщується у окре-мому рядку і закінчується числом, що дорівнює довжині самого короткого слова в ньому, за яким йде саме це слово. Вивести вміст вихідного і створеного файлів.
27. 	Створити текстовий файл. Кожен парний рядок вихідного файлу перепи-сати в перший новий текстовий файл, кожен непарний - у другий. У файлі з па-рними рядками змінити рядки таким чином, щоб слова кожного рядка були ле-ксично впорядковані за алфавітом. У файлі з непарними рядками лексично впо-рядкувати N перших рядків за алфавітом. Вивести вміст вихідного і створеного файлів.
28. 	Створити текстовий файл. Сформувати новий текстовий файл, що склада-ється з слів вхідного файлу, які зустрічаються у ньому менше N раз. Розмістити ці слова в новому файлі в порядку спадання їхньої довжини. Вивести вміст ви-хідного і створеного файлів.
29. 	Створити текстовий файл. Сформувати новий текстовий файл, що склада-ється з рядків вихідного файлу, розміщених у порядку спадання кількості сим-волів у них. На початку кожного рядка нового файлу вказати кількість символів у рядку. Вивести вміст вихідного і створеного файлів.
30. 	Створити текстовий файл. Переписати його компоненти до нового текс-тового файлу, вставляючи на початку рядка поточну довжину рядка у вихідному файлі, в кінці рядка – його порядковий номер. Вивести вміст вихідного і створеного файлів.

##	Контрольні питання
1.	Особливості організації текстових файлів у С/С++.
2.	Чим зумовлена потреба у відкритті та закритті файлів?
3.	Як визначається кінець файла у програмі?
4.	Чи можливий прямий доступ до рядків текстового файлу?
5.	Коли і для чого при обробці файлів застосовується функція fflush ?
6.	Чи можна в текстових файлах зберігати несимвольні дані ?