Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Основы.doc
Скачиваний:
58
Добавлен:
07.03.2016
Размер:
3.6 Mб
Скачать

11.3. Файли потокового введення/виведення з використанням структури file.

Функції введення/виведення потоком використовують структуру FILE. Ця структура і функції потокового введення/виведення описані у файлі <stdio.h> (<cstdio>).

typedef struct

{

short level;

unsigned flags;

char fd;

unsigned char hold;

short bsize;

unsigned char *buffer,

unsigned char *curp;

unsigned istemp;

short token;

} FILE;

Деякі з елементів структури FILE можуть бути корисні при програмуванні.

level – порожній або ні буфер введення/виведення;

flags – прапори стану файлу;

fd – номер файлового дескриптору;

hold – непереданий символ;

bsize – розмір буфера (зазвичай 512 байт);

buffer – значення вказівки – адреса початку буфера введення/виведення;

curp – положення поточної вказівки в буфері введення/виведення;

istemp – ознака (прапор) тимчасового файлу;

token – маркер дійсного файлу.

Прапори стану файлу приймають одне з наступних можливих значень, що задаються символьними константами:

_F_RDWR – файл відкритий для читання і запису;

_F_READ – файл відкритий тільки для читання;

_F_WRIT – файл відкритий тільки для запису;

_F_BUF – файл має виділений динамічний буфер даних;

_F_LBUF – порядковий буферизований файл;

_F_ERR – індикатор наявності помилки файлового доступу;

_F_EOF – кінець файлу;

_F_BIN – файл відкритий в двійковому режимі;

_F_IN – здійснюється читання з файлу;

_F_OUT – здійснюється запис у файл;

_F_TERM– файл є терміналом.

Відкриття потоків.

Потік має бути відкритий з використанням функцій fdopen, fopen, або freopen до виконання операцій введення/виведення з цим потоком. Стандартні потоки відкривати не потрібно.

Потік може бути відкритий:

1) тільки для читання;

2) тільки для запису;

3) для читання/запису одночасно;

4) для запису в кінець файлу (режим доповнення).

Крім того, потік може бути відкритий в текстовому або двійковому вигляді в будь-якому з цих випадків. Основною функцією для відкриття файлу потоком є функція fopen: FILE*fopen (char* pathname, char*type);

Функція відкриває файл, ім'я якого визначене в pathname. Це єдине місце в програмі, де ім'я файлу вказується явно. У pathname може бути вказано також і ім'я пристрою.

Type є символьним рядком, який визначає тип доступу, потрібний для файлу. Type може набувати наступних значень:

"r" – Відкрити для читання (файл повинен існувати).

"w" – Відкрити порожній файл для запису; якщо файл існує, то його вміст втрачається.

"а" – Відкрити для запису в кінець файлу (додавання); файл створюється, якщо він не існує.

"r+" – Відкрити для читання і запису (файл повинен існувати).

"w+" – Відкрити порожній файл для читання і запису; якщо файл існує, його вміст втрачається.

"a+" – Відкрити для читання і додавання; файл створюється, якщо він не існує.

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

Коли файл відкритий з "a" або "a+" типом, дані записуються в кінець файлу. Хоча вказівка файлу може бути переміщений, використовуючи fseek або rewind функції, але він завжди переміщатиметься назад на кінець файлу при записі даних. Таким чином, існуючі дані не можуть бути затерті.

Коли "r+", "w+" або "a+" типи визначені, читання і запис дозволені (якщо файл відкритий для оновлення). Проте перемикання з читання на запис повинне здійснюватися fseek або rewind командами. Поточна позиція може бути визначена для fseek команди, якщо необхідно.

Для задавання режиму відкриття файлу (текстового/двійкового) використовуються символи t і b. Ці символи записуються обов'язково після символів типу доступу. Наприклад, для відкриття двійкового файлу в режимі читання/запису можна записати тип у вигляді "r+b" або "rb+", але не у вигляді "br+" або "b+r" або ''+rb".

Функція fopen повертає вказівку на відкритий файл. У разі помилки повертається значення NULL.

Крім того, файл може бути відкритий за допомогою функцій fdopen і freopen. Функція fdopen дозволяє обробляти файл відкритий/створений за допомогою системи введення/виведення нижнього рівня засобами системи введення/виведення верхнього рівня.

Функція freopen закриває файл, пов'язаний з потоком stream і перепризначає потік stream на файл визначений в pathname.

FILE* freopen (char* pathname, char* type, FILE* stream);

Ця функція використовується для того, щоб зв'язати стандартні потоки stdin, stdout, stderr, stdaux і stdprn з файлами що задаються користувачем.

Операції введення-виведення.

1) int fscanf (FILE* stream, char* format [, adress]);

Ця функція виконує форматоване введення з потоку. Вона схожа на функцію scanf, за винятком того, що введення проводиться з потоку stream. Файл потоку має бути відкритий в текстовому режимі. Функція повертає число успішно введених полів.

2) int fprintf (FILE* stream, char* format [, adress]);

Ця функція виконує форматоване виведення в потік. Вона схожа на функцію printf, за винятком того, що виведення проводиться в потік stream. Файл потоку має бути відкритий в текстовому режимі.

3) int fgetc (FILE* stream);

Функція вводить символ з потоку stream. При успішному введенні функція повертає символ перетворений до типу int, без розширення знаку. Якщо виникла помилка, то функція повертає символ EOF. Ця функція успішно працює як в текстовому, так і в двійковому режимі.

4) int fputc (int c, FILE* stream);

Функція виводить символ c в потік stream. При успішному виведенні функція повертає символ "c". Якщо виникла помилка, то функція повертає символ EOF. Ця функція успішно працює як в текстовому, так і в двійковому режимі.

5) int fread (char* buf, unsigned size, unsigned n, FILE* stream);

Функція читає n елементів довжини size з потоку stream і поміщає їх в буфер buf. Функція повертає число прочитаних елементів. Якщо виникла помилка, або досягнутий кінець файлу то буде повернено число менше, ніж n. Ніяких перетворень форматів не проводяться. Цю функцію доцільно застосовувати для ефективного обміну даними в двійковому режимі, хоча можливе її застосування і в текстовому режимі.

6) int fwrite (char* buf, unsigned size, unsigned n, FILE* stream);

Функція виводить n елементів довжини size в потік stream з буфера buf. Функція повертає число виведених елементів.

Операції переміщення файлового покажчика (позиціонування) і допоміжні функції.

1) void rewind (FILE* stream);

Ця функція переміщує внутрішній покажчик на початок файлу. Вона схожа на описану нижче функцію fseek, викликану з параметрами fseek(stream, 0L, 0).

2) int fseek (FILE* stream, long offset, int fromwhere);

Ця функція переміщує внутрішній покажчик файлу в задане положення. Параметр offset задає зсув покажчика. Параметр fromwhere визначає місце, від якого відлічується зсув offset і може мати одне з трьох значень: 0, 1, 2. Ці константи позначені таким чином:

SEEK_SET – 0 – початок файлів;

SEEK_CUR – 1 – позиція поточного покажчика файлу;

SEEK_END – 2 – кінець файлу.

Функція повертає значення 0, якщо покажчик був успішно переміщений, і не 0, у разі помилки.

3) long ftell (FILE* stream);

Ця функція повертає поточне положення внутрішнього покажчика файлу. При помилці функція повертає EOF.

4) int feof (FILE* stream);

Функція виявляє кінець файлу пов'язаного з потоком stream. Ця функція повертає ненульове значення (EOF), якщо виявлений кінець файлу, інакше функція повертає 0. Ознака кінця файлу скидається при кожній операції введення.

5) int fflush (FILE* stream);

Функція записує на диск буфер, пов'язаний з потоком stream, якщо він був відкритий для виведення. Потік залишається відкритим після роботи цієї функції. Ця функція повертає нульове значення, якщо операція пройшла успішно, інакше функція повертає EOF.

6) int fflushall (void);

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

Закриття файлу.

1) int fclose (FILE* stream);

Функція закриває потік stream, при цьому записується на диск буфер, пов'язаний з потоком stream, якщо він був відкритий для виведення. Ця функція повертає нульове значення, якщо операція пройшла успішно, інакше функція повертає EOF. Якщо файл не закритий, то при нормальному закінченні програми він закривається автоматично.

2) int fcloseall (void);

Функція закриває всі відкриті потоки, окрім стандартних: stdin, stdout, stderr, stdaux, stdprn. Ця функція повертає нульове значення, якщо операція пройшла успішно, інакше функція повертає EOF.

Розглянемо приклад програми роботи з файлами. Записати масив у файл ot.txt, прочитати його і вивести на екран. Цей приклад є аналогом прикладу роботи з файлами, де було використано потік fstream. У нашому випадку використовується структура FILE. Зробимо це двома способами: з використанням текстових та бінарних файлів.

Приклад 1. Запис та читання масиву, використовуючи текстовий файл.

#include <iostream>

using namespace std;

void main()

{

int i;

int mas[10] = {1,20,300,4,50,600,7,80,900,10};

int vix[10];

FILE* file;

file = fopen("ot.txt", "w+");

for (i = 0; i < 10; i++)

fprintf(file,"%d ",mas[i]);

fseek(file,0L, SEEK_SET);

for (i = 0; i < 10; i++)

{

fscanf(file,"%d ",&vix[i]);

cout << vix[i] << " ";

}

fclose(file);

}

Приклад 2. Запис та читання масиву, використовуючи бінарний файл.

#include <iostream>

using namespace std;

void main()

{

int i;

int mas[10] = {1,20,300,4,50,600,7,80,900,10};

int vix[10];

FILE* file;

file = fopen("ot.txt", "w+");

fwrite(mas,10,sizeof(mas[0]),file);

fseek(file,0L, SEEK_SET);

fread(vix,10,sizeof(vix[0]),file);

for (i = 0; i < 10; i++)

cout << vix[i] << " ";

fclose(file);

}