Реферат Курсовая Конспект
Закриття файлу - Конспект, раздел Образование, Конспект лекцій СИСТЕМНЕ ПРОГРАМУВАННЯ Для Закриття Файлу Використовується Функція-Член| Close(). Наприклад, Щоб Зак...
|
Для закриття файлу використовується функція-член| close(). Наприклад, щоб закрити файл, пов'язаний з потоком mystream, необхідна наступна інструкція:
mystream.close ();
Функція close() не має аргументів і не повертає значення.
9.4.3 Функція eof()
За допомогою функції eof(), що є членом класу ios, можна визначити, чи був досягнутий кінець файлу вводу. Нижче представлений прототип цієї функції:
bool eof();
Функція повертає істину, якщо був досягнутий кінець файлу; інакше функціяповертає неправду.
9.4.4 Операції читання і запису для файлів
Після того, як файл відкритий, дуже легко прочитати з нього або записати в нього текстові дані. Просто потрібно використати оператори << та >> так само, як це робиться для консольного вводу – виводу; тільки потік cin або cout замінюється тим потоком, який пов'язаний з файлом.
Так само, як і оператори << та >>, для читання з файлу і запису у файл годяться функції C — fprintf() і fscanf(). Вся інформація у файлі зберігається в тому ж форматі, неначебто вона знаходиться на екрані. Отже, файл, створений за допомогою оператора <<, є файлом з відформатованим текстом. І навпаки, будь-який файл, вміст якого прочитується за допомогою оператора >>, повинен бути файлом з відформатованим текстом.
У представленій нижче програмі створюється файл для виводу, в нього записується інформація, і файл закривається. Потім файл знову відкривається вже як файл для вводу, і записана раніше інформація звідти прочитується:
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
ofstream fout("test"); // створення файлу для виводу
if(!fout)
{
cout << "Файл відкрити неможливо n";
return 1;
}
fout << "Привіт !n";
fout << 100 << ' ' << hex << 100 << endl;
fout.close ();
ifstream fin("test"); // відкриття файлу для вводу
if(!fin)
{
cout << "Файл відкрити неможливо n";
return 1;
}
char str[80];
int i;
fin >> str >> i;
cout << str << ' ' << i << endl;
fin.close ();
return 0;
}
Після роботи програми на диску залишиться файл з ім'ям "test", який міститиме інформацію, яка відформатована так, як якби вона видавалася на екран:
Привіт!
100 64
9.5 Двійковий неформатний ввід - вивід
Хоча текстові файли корисні в багатьох ситуаціях, у них немає гнучкості неформатних двійкових файлів. Неформатовані файли містять ті самі початкові або "сирі" двійкові дані, які безпосередньо використовуються програмою, а не зручний для сприйняття людиною текст, дані якого заради легкості для читання перетворюються операторами << та >>. Тому про неформатний ввід - вивід іноді говорять як про "сирий" (row) ввід - вивід.
В C++ для двійкових файлів підтримується широкий діапазон функцій вводу - виводу. Ці функції дають можливість точно контролювати процеси читання з файлів і запису до файлів.
9.5.1 Основні| функції двійкового вводу - виводу
На нижньому рівні двійкового вводу - виводу знаходяться функції get() і put(). За допомогою функції-члена put() можна записати байт, а за допомогою функції-члена get() — прочитати. Ці функції є членами всіх потокових класів відповідно для вводу і для виводу. Функції get() і put() мають багато форматів. Нижче представлені їх варіанти, що найбільш часто зустрічаються в програмах:
istream &get (char &ch);
ostream &put(char ch);
Функція get() прочитує один символ з пов'язаного з нею потоку і передає його значення аргументу ch. Значенням, що вона повертає, є посилання на потік. При прочитуванні символу кінця файла функціяповерне викликаючому потоку значення false. Функція put() записує символ ch у потік і повертає посилання на потік.
Для прочитування і запису блоків двійкових даних використовуються функції read() і write(), які також є членами потокових класів для вводу і для виводу, відповідно. Нижче приведені їх прототипи:
istream &read(char *buffer, streamsize size);
ostream &write (const char *buffer, streamsize size);
Функція read() прочитує із викликаючого потоку стільки байтів, скільки задано в аргументі size і передає їх в буфер, визначений вказівником buffer. Функція write() записує у відповідний потік з буфера, який визначений вказівником buffer, задане в аргументі size число байтів. Тип streamsize є різновидом цілого.
Якщо кінець файлу досягнутий до того, як було прочитано size символів, виконання функції read() просто припиняється, а в буфері буде знаходитись стільки символів, скільки їх було у файлі. Дізнатися, скільки символів було прочитано, можна за допомогою іншої функції-члена gcount(), прототип якої приведений нижче:
streamsize gcount();
Ця функціяповертає кількість символів, прочитаних під час останньої операції двійкового вводу.
Природно, що при використанні функцій, призначених для роботи з двійковими файлами, файли повинні відкриватися в двійковому, а не в текстовому режимі. Значення режиму відкриття файлу ios::binary запобігає якому б то не було перетворенню символів. Це важливо, коли у файлі зберігаються двійкові дані, наприклад, цілі, дійсні числа або вказівники.
Проте для файлу, відкритого в текстовому режимі, хоча в ньому міститься тільки текст, двійкові функції цілком доступні; при цьому потрібно пам'ятати про можливість небажаного приведення символів.
В наступній програмі спочатку масив чисел з плаваючою крапкою подвійної точності записується у файл, а потім прочитується назад. За допомогою функції gcount() відображається число прочитаних символів:
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
ofstream out("test", ios::out | ios::binary);
if(!out)
{
cout << "Не можна відкрити файл для виводу. n";
return 1;
}
double nums[4]= {1.1, 2.2, 3.3, 4.4 };
out.write((char *) nums, sizeof(nums));
out.close();
ifstream in("test", ios::in | ios::binary);
if(!in)
{
cout << "Не можна відкрити файл для вводу. n";
return 1;
}
in.read((char *) &nums, sizeof(nums));
int i;
for(i=0; i<4; i++)
cout << nums[i]<< ' ';
cout << 'n';
cout << in.gcount() << " символів прочитано. n";
in.close();
return 0;
}
9.5.2 Додаткові функції двійкового вводу - виводу
Окрім представленого раніше варіанту, функцію get() можна перевантажувати ще декількома способами. Нижче приведені прототипи трьох найчастіше використовуваних форматів цієї функції:
istream& get(char *buffer, streamsize size);
istream& get(char *buffer, streamsize size, char d);
int get();
Перша функціяget() прочитує символи в буфер, заданий вказівником buffer, до тих пір, поки або буде прочитано стільки символів, скільки задано аргументом size - 1, або не зустрінеться символ кінця файлу. В кінці буфера, заданого вказівником buffer, функція get() поміщає нуль. Якщо в потоці вводу зустрівся символ нового рядка, він не вибирається з потоку, а залишається в потоці до наступної операції вводу.
Друга функціяget() прочитує символи в буфер, заданий вказівником buffer, до тих пір, поки або буде прочитано стільки символів, скільки задано аргументом size - 1, або не зустрінеться символ, заданий аргументом d (символ – обмежувач), або не зустрінеться символ кінця файлу. В кінець буфера, заданого вказівником buffer, функція get() поміщає нуль. Якщо в потоці вводу зустрінеться символ - обмежувач, він не вибирається, а залишається в потоці до наступної операції вводу.
Третя функціяget() вибирає з потоку черговий символ. Вона повертає символ EOF, якщо буде досягнутий кінець файлу. Ця форма get() нагадує функцію getc() мови С.
Іншою функцією для реалізації вводу є функціяgetline(). Ця функція є членом всіх потокових класів вводу. Нижче приведені її прототипи:
istream& getline(char *buffer, streamsize size);
istream& getline(char *buffer, streamsize size, char d);
Перша функціяgetline() прочитує символи в буфер, заданий вказівником buffer, до тих пір, поки або буде прочитано стільки символів, скільки задано аргументом size - 1, або не зустрінеться символ нового рядка, або символ кінця файлу. В кінці буфера, заданого вказівником buffer, функція getline() поміщає нуль. Якщо в потоці вводу зустрінеться символ нового рядка, він вибирається з потоку, але не поміщається в буфер.
Друга функціяgetline() прочитує символи в буфер, заданий вказівником buffer, до тих пір, поки або буде прочитано стільки символів, скільки задано аргументом size - 1, або не зустрінеться символ, заданий аргументом d (символ – обмежувач рядка), або не зустрінеться символ кінця файлу. В кінець буфера, заданого вказівником buffer, функція getline() поміщає нуль. Якщо в потоці вводу зустрінеться символ – обмежувач рядка d, він вибирається, але не поміщається в буфер.
Як можна помітити, обидві версії функції getline() фактично тотожні варіантам функції get() з відповідними аргументами. Обидві прочитують символи з потоку вводу і поміщають їх в буфер, заданий вказівником buffer, до тих пір, поки або не прочитано size - 1 символів, або не зустрівся символ – обмежувач, або символ кінця файлу. Відмінність між функціями get() і getline() у тому, що функціяgetline() прочитує і видаляє з потоку вводу символ - обмежувач, а функція get() - ні.
Використовуючи функцію peek(), можна одержати наступний символ з потоку вводу без його видалення з потоку. Функція є членом потокових класів вводу і має наступний прототип:
int peek();
Функція повертає наступний символ з потоку або, якщо був досягнутий кінець файлу, символ EOF.
За допомогою функції putback(), що є членом потокових класів вводу, можна повернути останній прочитаний з потоку символ назад в потік. Нижче приведений прототип цієї функції:
ifstream putback(char c);
Тут c - це останній прочитаний з потоку символ.
При виконанні виводу дані не відразу записуються на пов'язаний з потоком фізичний пристрій, а інформація тимчасово зберігається у внутрішньому буфері. Тільки після заповнення буфера його вміст передається на носій. Проте виклик функції flush() викликає фізичний запис інформації на носій до заповнення буфера. Нижче показаний прототип
функції flush(), що є членом потокових класів виводу:
ostream &flush();
Виклики функції flush() виправдані при роботі у несприятливій обстановці, наприклад, в ситуаціях, коли часто трапляються збої по живленню.
Нижче наводиться приклад програми, що використовує функції peek() і putback(), оскільки вони особливо корисні в реальному програмуванні. Ці функції дозволяють спростити управління, коли невідомий тип інформації, що вводиться в кожен конкретний момент часу. У програмі з файлу прочитуються цілі числа або рядки символів. Рядки й цілі можуть слідувати в будь-якому порядку:
#include <iostream>
#include <fstream>
#include <cctype>
using namespace std;
int main()
{
char ch;
ofstream out("test", ios::out | ios::binary);
if(!out)
{
cout << "Не можна відкрити файл для виводу. n";
return 1;
}
char str[80] *p;
out << 123 << "this is а test" << 23;
out << "Hello there!" << 99 << "sdf" << endl;
out.close();
ifstream in("test", ios::in | ios::binary);
if(!in)
{
cout << " Не можна відкрити файл для вводу. n";
return 1;
}
do
{
p = str;
ch = in.peek();
if(isdigit(ch)) // визначення типу чергового символу
{
while(isdigit(*p=in.get())) p++; // читання цілого
in.putback(*p); // повернення символу в потік
*p = ' '; // закінчуємо рядок нулем
cout << "Ціле: " << atoi(str);
}
else if(isalpha(ch))
{
while(isalpha(*p=in.get())) p++; // читання рядка
in.putback(*p); // повернення символу в потік
*p = ' '; // закінчуємо рядок нулем
cout << "Рядок: " << str;
}
else
in.get(); // пропуск
cout << 'n';
} while(!in.eof());
in.close();
return 0;
}
9.6 Довільний доступ
У системі вводу – виводу мови C++ довільний доступ (random access) реалізується за допомогою функцій seekg() і seekp(), що є потоковими функціями відповідно вводу і виводу. Нижче приводяться їх основні| прототипи:
istream& seekg(off_type disp, seekdir dir);
ostream& seekp(off_type disp, seekdir dir);
Тут off_type — це цілий тип даних, оголошений в класі ios і сумісний з максимальним правильним значенням, яке здатний зберігати аргумент віддалення у файлі disp. Тип seekdir — це перелік, що оголошений в класі ios і містить наступні значення:
ios::beg – віддалення від початку файлу;
ios::cur – віддалення від поточної позиції у файлі;
ios::end - віддалення від кінця файлу.
Система вводу - виводу C++ управляє двома вказівниками, пов'язаними з файлом. Перший — це вказівник зчитування (get pointer), який задає наступне місце у файлі, звідки буде вводитися інформація. Другий - це вказівник запису (put pointer), який задає наступне місце у файлі, куди буде виводитися інформація. При кожному вводі або виводі відповідний вказівник послідовно просувається далі. Проте за допомогою функцій seekg() і seekp() можливий непослідовний доступ до файлу.
Функція seekg() встановлює вказівник зчитування відповідного файлу в позицію, що відстоїть| на величину віддалення disp від заданого місця dir. Функція seekp() встановлює вказівник запису відповідного файлу в позицію, що відстоїть| на величину віддалення disp від заданого місця dir.
Як правило, файли, доступні для функцій seekg() і seekp(), повинні відкриватися в режимі операцій для двійкових файлів. За допомогою цього режиму виключається можливе несподіване перетворення символів усередині файлу.
Визначити поточну позицію кожного з двох вказівників можна за допомогою функцій:
pos_type tellg();
pos_type tellp();
У прототипах pos_type - це цілий тип даних, оголошений в класі ios і здатний зберігати найбільше можливе значення вказівника.
Для переміщення файлових вказівників зчитування і запису на позицію, задану значеннями, що повертають функції tellg() і tellp(), використовуються перевантажені версії функцій seekg() і seekp(), прототипи яких представлені нижче:
istream& seekg (pos_type pos);
ostream& seekp(pos_type pos);
У наступній демонстраційній програмі функціяseekg() використовується для установки вказівника зчитування в задану позицію всередині файлу і для виводу вмісту файлу, починаючи з цієї позиції. Ім'я файлу і позиція зчитування задаються в командному рядку:
#include <iostream>
#include <fstream>
#include <cstdlib>
using namespace std;
int main(int argc, char *argv[])
{
char ch;
if(argc!=3)
{
cout << "Пошук: <файл> <позиція> n";
return 1;
}
ifstream in(argv[1], ios::in | ios::binary);
if(!in)
{
cout << "Файл відкрити неможливо. n";
return 1;
}
in.seekg(atoi(argv[2]), ios::beg);
while(!in.eof())
{
in.get(ch);
cout << ch;
}
in.close();
return 0;
}
– Конец работы –
Эта тема принадлежит разделу:
Конспект лекцій... по дисциплiні СИСТЕМНЕ ПРОГРАМУВАННЯ...
Если Вам нужно дополнительный материал на эту тему, или Вы не нашли то, что искали, рекомендуем воспользоваться поиском по нашей базе работ: Закриття файлу
Если этот материал оказался полезным ля Вас, Вы можете сохранить его на свою страничку в социальных сетях:
Твитнуть |
Новости и инфо для студентов