Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Глинський С++.docx
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
2.26 Mб
Скачать

Тема 6. Файли

Часто виникає потреба опрацьовувати інформацію, розмі­щену на зовнішніх носіях (на дисках), або виводити результа­ти програми не на екран монітора, а у файл. Прикладами та­ких даних є інформація про розклад руху транспорту, успіш­ність студентів, наявність товарів у магазинах, адреси, ан­кетні дані тощо.

Файл це сукупність даних, які розміщені на зовнішньо­му носії, зокрема, на жорсткому диску. Дані у файлі назива­ються елементами. Кількість даних під час опрацювання фай­лів не зазначають. Файли можуть містити як текстову, так і числову інформацію.

Існує декілька бібліотечних функцій, які дають змогу зчи­тати інформацію з файлу або спрямовувати потік виведення у файл. Функції, які розглядатимемо, описані в бібліотеці fstream.h. Тому для роботи з файлами насамперед необхідно підключити саме цю бібліотеку.

Зауваження 1. У модулі fstream.h також містяться описи стан­дартних потоків cout і сіn. Тому, щоб зчитати інформацію з файлу і вивести її на екран монітора, модуль iostream.h під­ключати в деяких компіляторах не обов’язково(в dev c++ потрібно).

Для опрацювання файлу його необхідно відкрити, виконати потрібні дії та закрити.

  1. Зчитування даних із файлу. Щоб зчитати вхідні дані з файлу, необхідно оголосити файлову змінну та відкрити файл для читання так (розглянемо два способи):

ifstream <назва файлової змінної>(<зовнішня назва>, ознака1 |ознака2 | ... | ознакаN);

або так:

ifstream <назва файлової змінної>;<назва файлової змінної>.ореn(<зовнішня назва>);

Дія команд. Підключаємо потік введення даних із файлу та налагоджуємо зв’язок між файловою змінною у програмі та файлом на зовнішньому носії. Назву зовнішнього файлу треба записувати у лапках. Ознаки слугують для визначення прав доступу до файлу (див. пункт „Ознаки”). Ознаки зазначати необов'язково. У випадку, коли їх задавати не потрібно, наве­дені дві форми запису тотожні, і можна обирати одну з них.

Приклад 1. Відкрити зовнішній файл MyText.txt для читання з нього даних можна так:

ifstream MyFile("MyText.txt");

або так:

ifstream MyFile; MyFile.open("MyText.txt");

Тут MyFile - це файлова змінна, що асоціюється у програмі з відповідним зовнішнім файлом на диску. Введення даних виконують командою введення >>.

Наприклад, команда MyFile >> text;

зчитає одне дане з початку файлу MyText.txt до першого про­пуску чи до символу „кінець рядка” у змінну text. Якщо треба зчитати наступне дане (яке розміщене між першим і другим пропусками), необхідно повторити попередню команду, тобто записати команди MyFile >> text;

MyFile >> text1;

або використати команду

MyFile >> text >>text1;.

Отже, зчитати дані з файлу можна за допомогою команди:

< назва файлової змінної> >> <змінна 1> >> <змінна 2> >> ... >> <змінна N>

Після опрацювання файлу його потрібно закрити. Це роб­лять так:

<назва файлової змінної>.сlosе()

Наприклад, MyFile.close(). Файл MyText.txt буде закрито. Після цього файлову змінну MyFile у разі потреби можна зв’язати з іншим файлом на диску.

Визначити кінець файлу можна за допомогою функції eof() (eof - end of file, кінець файлу):

<назва файлової змінної>.еоf()

Ця функція повертає нульове значення, якщо досягнуто кінця файлу.

Приклад 2. Нехай у деякому текстовому редакторі створе­но файли text1.dat і text2.dat. Послідовно зчитаємо з них да­ні та виведемо їх вміст на екран.

#include <iostream> // std::cout

#include <fstream> // std::ifstream

//using namespace std; //необхідно для ifstream та cout, але в цій програмі оголошено явно

int main()

{

std::ifstream File1 ("text1.dat"); //Поки не досягнуто кінця файлу text1.dat

while (!File1.eof()) // Знак ! означає операцію не

{

char *t = new char[30]; // Надаємо місце в пам'яті для зчитуваного даного до 30 символів

File1>> t; // Зчитуємо дане з файлу

std::cout << t << "\n"; // Виводимо це дане на екран

delete [] t; // Вивільняємо пам'ять

}

//Повертаємось на початок команди while

File1.close(); // коли досягнуто кінця файлу, закриваємо його

File1.open("text2.dat"); // Відкриваємо файл text2.dat для читання

while (! File1 .eof()) // Поки не досягнуто кінця файлу

{

char *t = new char[30];

File1 >>t;

std::cout << t << "\n"; delete[] t;

}

File1.close();

}

Детальніше про команду while див. у § 9. Оскільки у програ­мі виділяється пам’ять відразу для 30 символів, то використову­ємо команду delete[] (див. § 12).

  1. Виведення даних у файл. Відкрити файл для запи­сування у нього даних можна так:

ofstream <назва файлової змінної>(<зовнішня назва>,ознака1 | ознака2 |... | ознакаN)

aбо так:

ofstream <назва файлової змінної>; <назва файлової змінної>.ореn(<зовнішня назва>);

Дія команд. Підключаємо потік виведення у файл і нала­годжуємо зв’язок між файловою змінною у програмі та фай­лом на зовнішньому носії. Ознаки зазначати не обов’язково.

Приклад 3. Відкрити файл MyTextl.txt для запису у ньо­го даних можна так (тут FileForZap - файлова змінна):

ofstream FileForZap("MyText1 .txt");

або так:

ofstream FileForZap; FileForZap.open("MyTextl .txt");

Щоб занести дані у файл, використовують команду виве­дення даних <<. Наприклад, після виконання команд int n = 10; FileForZap << n; у файл MyTextl.txt буде занесено число 10. Занести декілька даних у файл можна так само, як і вивести їх на екран: вико­ристовуючи стандартні правила команди << та керуючі послі­довності.

Отже, записати дані у файл можна так:

<назва файлової змінної> << <змінна 1> << <змінна 2> << ... << <змінна N>

  1. Ознаки. Ознаки слугують для зміни правил доступу до файлу. Розглянемо деякі з них:

Ознака

Призначення

ios::in

Відкриває файл для читання з нього інформа­ції. Вміст файлу зберігається

ios::out

Відкриває файл для записування інформації. Якщо файл не існує, то буде створений

ios::app

Відкриває файл для дописування інформації. Дані будуть записані у кінець файлу

ios::trunk

Якщо файл, який відкривають для записування вже існує, то його вміст буде вилучено

ios::nocreate

Забороняє створювати файл, який відкривають

ios::noreplace

Забороняє перезаписати існуючий файл

Приклад 4. Після оголошення

ofstream Flags("text1.dat", ios::app, ios::noreplace);

можна дописати до кінця вже існуючого файлу text1.dat потрібну інформацію.

Якщо ж оголосити потік Flags так:

ofstream Flags("text1.dat", ios::noreplace);

і спробувати щось записати у файл, то жодних дій не відбу­деться, оскільки ознака ios::noreplace забороняє змінювати існу­ючий файл. Проте якщо цю ознаку застосувати до нового файлу, якого ще немає на диску, наприклад, записати

ofstream Flags(“text3.dat", ios::noreplace);

то буде створено файл text3.dat, в який можна буде заносити дані.

Якщо потік оголосити так:

ofstream Flags("text4.dat", ios::nocreate);

то можливі два варіанти. Якщо файл text4.dat вже існує, то він може бути відкритий для записування даних. Якщо ж ра­ніше такого файлу на диску не було, то в кращому випадку у файл нічого не запишеться, а в гіршому - програма зависне.

Задача 1 (про змагання спортсменів). Нехай необхідно за­нести у файл прізвища та результати трьох переможців зма­гань із фігурного катання. Вивести вміст файлу на екран для візуального контролю.

// Програма Спорт

#include <iostream> // std::cout, сіn

#include <fstream> //std::ofstream, ifstream

using namespace std;

int main()

{

//Відкриємо файл для записування

ofstream File1 ("sport.txt");

char name[15];

float bal;

cout << "Уведіть прізвище та результат першого спортсмена\n";

cin >> name >> bal;

File1 << name << "\t" << bal << "\n"; // Записуємо дані у файл

cout << "Уведіть прізвище та результат другого спортсмена\n";

cin >> name >> bal;

File1 << name << "\t" << bal << "\n"; // Записуємо дані у файл

cout << "Уведіть прізвище та результат третього спортсмена\n";

cin >> name >> bal;

File1<<name << "\t" " bal " "\n";

File1.close(); // Закриваємо файл

cout << "Виведемо вміст файлу\n";

ifstream File2("sport.txt");

cout << "Перше місце \t";

File2 >> name>> bal; // Зчитуємо дані з файла

cout << name << "\t" << bal <<"\n";

cout << "Друге місце \t"; File2 >> name >> bal;

cout << name << "\t" << bal << "\n";

cout << "Третє місце \t";

File2 >> name >> bal;

cout << name << "\t" << bal << "\n";

}

4. Закриття файлів

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

Для того, щоб на диск записувати по-рідше, але по-більше за раз, дані спочатку пишуться в буфер оперативної пам'яті, а коли буфер заповнюється, все це разом зливається вже на диск.

Закриття потоку гарантує, що будь-які дані, що знаходяться в буфері і ще не записані на диск, будуть туди записані.

 Відсутність цієї команди може призвести до втрати даних у файлі, який був відкритий для запису (дозаписи).

Якщо не закривати файли (які відкриті навіть для читання), то це може призвести до обмеження доступу до файлу для інших програм.

В ОС Windows якщо файл відкритий на читання і не закривається, то з іншої програми його не можна видалити.

У будь-якій ОС є обмеження на кількість одночасно відкритих файлів. І це ще одна причина для закриття файлів.

Вправи

  1. Модифікуйте програму Спорт так, щоб записати у файл прізвище, місце та результат спортсмена. Зчитайте інформацію з файлу та виведіть її на екран для контролю.

  2. У текстовому редакторі створіть файл druzi.txt, у який занесіть прізвища п’яти ваших друзів. Складіть програму, яка б додавала інформацію ще про трьох осіб і результати записувала у файл druzil.txt. Ви­ведіть уміст файлів druzi.txt і druzil.txt на екран.

  3. У текстовому редакторі створіть файл, у який занесіть координа­ти вершин трикутника. Розв’яжіть задачу № 2 вашого варіанта, використовуючи утворений файл. Результати виведіть на екран і у файл.

12.1.1, 12.1.2, 12.1.8, 12.2.1,12.8.1

Zubenko-Omelchuk 3.10.5, стор.424

Burn Straustrup 21.5, стор. 751