
- •12. Класи пам'яті даних 100
- •13. Робота з файлами 106
- •14. Посилання 111
- •Склад мови
- •Алфавіт мови
- •Лексеми
- •Ключові слова
- •Ідентифікатори
- •Константи
- •Символьні рядки
- •Знаки операцій, роздільники, коментарі
- •Типи даних
- •Класифікація типів даних
- •Цілочислові типи
- •Дійсні типи
- •Оголошення змінних і констант
- •Переліки
- •Структура програми
- •Функція main
- •Область дії змінної
- •Введення і виведення даних
- •Функції стандартної математичної бібліотеки
- •Вирази і операції
- •Поняття виразу, операнда, операції
- •Порядок виконання операцій
- •Арифметичні операції
- •Порозрядні операції
- •Операції порівняння
- •Логічні операції
- •Операції присвоєння
- •Умовна операція
- •Операція визначення розміру sizeof
- •Узгодження типів у виразах
- •Умовні оператори
- •Оператори
- •Умовний оператор if
- •Оператор вибору switch
- •Оператори циклу
- •Цикл з параметром. Оператор for
- •Цикл з передумовою. Оператор while
- •Цикл з постумовою. Оператор do while
- •Оператори переходу
- •Використання псевдовипадкових чисел
- •Одновимірні масиви
- •Багатовимірні масиви
- •Символьні рядки
- •Вказівники
- •Оголошення вказівника, операції, пов’язані з вказівниками
- •Адресна арифметика
- •Void – вказівники, типізація вказівників
- •Звертання до елементів масивів через вказівники
- •Масиви символьних рядків і масиви вказівників
- •Динамічне виділення пам’яті
- •Структури і об’єднання
- •Оголошення і ініціалізація структур
- •Звертання до елементів структур
- •Перейменування типів
- •Об’єднання
- •Поля бітів
- •Директиви препроцесора
- •Призначення директив препроцесора
- •Директива включення #include
- •Директиви макропідстановок #define I #undef
- •Директиви умовної компіляції
- •Директиви #ifdef, #ifndef
- •Функції
- •Структура функції
- •Виклик функцій. Прототипи функцій
- •Взаємодія фактичних і формальних параметрів функцій
- •Inline – функції
- •Масиви і символьні рядки як параметри функцій
- •Використання кваліфікатора const в оголошеннях параметрів
- •Багатовимірні масиви як параметри функцій
- •Опрацювання структур у функціях
- •Вказівники на функції
- •Рекурсивні функції
- •Класи пам'яті даних
- •Клас пам'яті, час існування і видимість об’єкта
- •Область дії глобальних і локальних змінних
- •Специфікатори класів пам'яті
- •Специфікатори глобальних змінних
- •Багатофайлові програми
- •Робота з файлами
- •Звертання до файлів
- •Послідовний запис до файлу і послідовне читання з файлу
- •Файли з довільним доступом
- •Посилання
- •Призначення посилань
- •Передача аргументів функцій як посилань
Робота з файлами
Звертання до файлів
Для роботи з файлами необхідно підключити бібліотеку fstream. Файл, як і будь-яку іншу змінну, необхідно оголосити. Це можна зробити таким чином:
ofstream fn ( "test.txt", ios::app );
Тут fn – змінна, за допомогою якої будуть виконуватись звертання до файлу з програми, test.txt – ім’я файлу на диску, ios::app – режим звертання до файлу.
Існують такі режими звертання до файлу: ios::in – читання з файлу, для потоку ifstream встановлюється за замовчуванням, курсор встановлюється в початок файлу за замовчуванням; ios::out – запис поверх існуючої, для потоку ofstream встановлюється за замовчуванням, курсор встановлюється в початок файлу за замовчуванням; ios::ate – запис і зчитування, запис поверх існуючої, курсор встановлюється в початок файлу за замовчуванням; ios::app – запис, додавання в кінець файлу після існуючого запису.
Таким чином, команда з останнього приклада буде відкривати файл з іменем test.txt, який знаходиться в тому самому каталозі, що і програма. Файл відкривається для запису, якщо файл не існує – він буде створений.
Для того, щоб відкрити файл як для зчитування, так і для запису, необхідно виконати таку команду:
ifstream fn ( "test.txt", ios::in | ios::out );
Тут два аргумента ios::in і ios::out об’єднані за допомогою оператора |. Результат виконання цієї операції можна перевірити таким чином:
if ( !fn ) {
cout << "Error opening file\n";
exit( 1 );
}
В результаті виконання функції exit програма завершається. Аргумент цілого типу може приймати будь-яке значення, але традиційно вважають, що значенню аргументу 1 відповідає завершення програми через помилку, значенню аргумента 0 – нормальне завершення програми.
Після використання файлу його необхідно закрити:
fn.close();
Послідовний запис до файлу і послідовне читання з файлу
Для запису інформації до файлу використовують операцію, яка є аналогом операції cout <<:
fn << блок 1 << блок 2 << … << блок n;
Запишемо в файл деяку інформацію:
#include <iostream>
#include <fstream>
using namespace std;
int main( ) {
ofstream fn ( "test.txt", ios::out );
if ( !fn ) {
cout << "Error opening file\n";
exit( 1 );
}
fn << "Line 1" << endl << "Line 2";
fn.close();
}
Для читання з файлу використовують операцію, яка є аналогом операції cin >>:
fn >> блок 1 >> блок 2 >> … >> блок n;
Виведемо на екран зміст файлу, який був створений попередньою програмою:
#include <iostream>
#include <fstream>
using namespace std;
int main( ) {
char buf[ 20 ];
ifstream fn ( "test.txt", ios::in );
if ( !fn ) return 1;
while ( ! fn.eof() ) {
//fn >> buf; // Зчитати слово з файлу
fn.getline( buf, sizeof( buf ) );
cout << buf << endl;
}
fn.close();
}
Дані будуть читатися до тих пір, поки не буде досягнуто кінець файлу – в цьому випадку функція fn.eof() поверне нульове значення. Для читання з файлу можна використовувати оператор fn >> buf; який прочитає з файла слово і запише його в масив buf. Слово закінчується першим пробільним символом. Для того, щоб прочитати рядок символів, можна використовувати функцію fn.getline( buf, sizeof( buf ) ); Аргументами функції є адреса буфера, в якому необхідно зберегти прочитаний рядок, і розмір цього буфера.
При збереженні чисел в файлі їх зручно відділяти одне від одного одним чи декількома пробільними символами:
#include <iostream>
#include <fstream>
using namespace std;
int main( ) {
ofstream fout ( "test.txt", ios::out );
if ( !fout ) return 1;
for ( int i = 1; i <= 10; i++ )
fout << i << " " << double( i ) / ( i + 1)
<< ( i < 10 ? "\n" : "" );
fout.close();
int t;
double d;
ifstream fin ( "test.txt", ios::in );
if ( !fin ) return 1;
while ( ! fin.eof() ) {
fin >> t >> d;
cout << t << "\t" << d <<endl;
}
fin.close();
}
Так само можна читати рядки символів. Але необхідно пам’ятати, що операція >> буде повертати одне слово.
#include <iostream>
#include <fstream>
using namespace std;
int main( ) {
ofstream fout ( "test.txt", ios::out );
if ( !fout ) return 1;
fout << "One " << 1 << endl;
fout << "Two " << 2;
fout.close();
char c[ 10 ];
int t;
ifstream fin ( "test.txt", ios::in );
if ( !fin ) return 1;
while ( ! fin.eof() ) {
fin >> c >> t;
cout << c << "\t" << t <<endl;
}
fin.close();
}