- •Лабораторна робота №11 (2 год.) Робота з файлами. Файлові потоки.
- •Теоретичні відомості
- •2. Потоки як узагальнені фільтри
- •Приклад 1. Простий приклад потокового вводу-виводу
- •3. Введення-виведення типів char I char*
- •4. Введення-виведення типів int I long
- •5. Введення-виведення типів float I double
- •6. Введення-виведення класів користувача
- •Приклад 3. Ввід-вивід класу користувача
- •7. Маніпулятори
- •8. Використання текстових файлів для введення
- •Приклад 4. Читання і перевірка файлу на помилки
- •9.Виведення текстових файлів
- •10. Читання бінарних файлів
- •Приклад 6. Читання текстового файлу в бінарному режимі
- •11. Запис у бінарні файли
- •12. Копіювання файлів
- •1. Потоки і потік введення - виведення
- •2. Текстові і двійкові потоки
- •3. Буферизація потоків
- •4. Стандартні потоки
- •5. Приклад програми роботи з файлами
- •6. Різниця при роботі з файлами у мовах Паскаль та с
- •Завдання
Приклад 6. Читання текстового файлу в бінарному режимі
#include <iostream.h>
#include <fstream.h>
void main()
{
//відкриття існуючого файлу
ifstream help_file(“\\BC45\\README”, ios::binary);
//перевірка на помилки відкриття файлу
if(!help_file)
{
cout << “\nCouldn’t open file \\BC45\\README”;
return;
}
//відображення файлу readme
while(help_file)
{
char c;
help_file.get(c);
cout << c;
}
}
Істотною відмінністю між обробкою текстовий і двійкових фалів є використання операторів вилучення даних з потоку. Оскільки двійкові дані розглядаються як неформатовані, гарантована робота лише механізму вилучення символів. Якщо вилучені символи поміщуються в символьний буфер, то повинен бути вказаний розмір буфера:
char buffer[100];
help_file.read(buffer,sizeof(buffer));
11. Запис у бінарні файли
Для запису бінарних даних в файл існує два основних методи: посимвольний запис і запис блоками. Для першого методу використовується функція put(char), для другого – функція write(char*, int). В прикладі 7 продемонстрована робота обох функцій.
Приклад 7. Запис двійкових даних в файл за допомогою двох методів
#include <iostream.h>
#include <fstream.h>
class Data {
char name[10];
char surname[20];
int age;
float salary;
public:
Data() {age=0;}
int Age() {return age;}
~Data() {}
};
void main()
{
//відкриття існуючого файлу
ofstream company_records(“RECORDS.DAT”,
ios::binary);
//перевірка на помилки відкриття
if(!company_records)
{
cout << “\nCouldn’t open file RECORDS.DAT”;
return;
}
Data employee;
int number=0;
while(number < 10 && company_records)
{
company_records.put((char)number++);
company_records.write((char*)&employee,
sizeof(employee));
}
}
Програма записує 10 записів про службовців з об’єкту класу в двійковий файл. Як і завжди, потік слід перевірити на помилки читання або запису. Використання функції write(...) з класами, що мають віртуальні функції або інші складні конструкції, деколи призводить до запису даних, які потім неможливо правильно прочитати за допомогою функції read(...). якщо є сумніви, при записі складних даних краще працювати зі структурами, ніж з класами.
Бінарні файли, в порівнянні з текстовими, складніше використовувати. Це результат неструктурованої природи даних. Коли в файл поміщується бінарний об’єкт, компілятору потрібно точно вказати, яка довжина об’єкту, оскільки в двійковому файлі немає роздільників стрічок, що вказують на довжину. Те ж саме можна сказати і про вилучення даних.
12. Копіювання файлів
Програми часто читають один файл, роблять щось з даними і потім копіюють їх в інший файл. Копіювання файлів може виконуватися за допомогою класів iostream різними способами, деякі з них досить зручні. Концептуально найпростіший спосіб – читати і писати по одному символу до тих пір, поки не буде досягнуто кінець файлу вводу. Наступний код показує, як це зробити на практиці:
#include <fstream.h>
void f()
{
ifstream input(“c:\\t.bat”);
ofstream output(“c:\\u.bat”);
char c;
while(input.get(c))
output.put(c);
}
ІІ. Засоби мови С для роботи з потоками