Функции позицирования в файлах

При выполнении операций чтения - записи в файле требуется иногда перемещать указатель текущей позиции файла, например, при переходе от чтения к записи или наоборот (когда файл открыт в комбинированных режимах). Для перемещения указателя существуют специальные функции.

Функция для установки указателя текущей позиции в заданное положение:

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

параметры: stream – указатель на структуру FILE, offset – смещение в байтах указателя текущей позиции от позиции, заданной следующим параметром, fromwhere – возможные значения заданы константами: SEEK_SET – начало файла, SEEK_CUR – текущее положение указателя, SEEK_END – конец файла. Возвращаемое значение: 0, если функция нормально завершает свою работу, не 0 – в случае ошибки.

Функция для установки указателя текущей позиции в начало файла:

void rewind(FILE * stream);

параметр stream – указатель на структуру FILE.

Функция для получения текущего положения указателя позиции файла (смещение в байтах от начала файла):

long ftell(FILE * stream);

параметр stream – указатель на структуру FILE, функция возвращает текущее положение указателя.

 

Функции для сброса буферов ввода- вывода

Иногда требуется явно проводить сброс буфера ввода- вывода. В частности, эта операция обязательна при переходе от операции записи к операции чтения (при открытии файла в комбинированном режиме), чтобы записанные данные гарантированно оказались записаны в файле.

Функция сброса заданного буфера ввода- вывода:

int fflush(FILE * stream);

параметр stream – указатель на структуру FILE, функция возвращает 0 – в случае нормального завершения и EOF – в случае ошибки.

Функция сброса всех буферов ввода- вывода:

int flushall();

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

Задачи и порядок выполнения работы

В лабораторной работе необходимо разработать два приложения. В первом приложении исходные данные вводятся с клавиатуры (количество объектов, заданных структурным типом, заранее неизвестно) и сохраняются в файле. Во втором приложении данные, сохраненные в первом приложении в файле, читаются из файла и выводятся на экран. В зависимости от варианта данные могут сохраняться в файле как в текстовом, так и в двоичном режиме.

 

Пример выполнения работы

Условие задачи:

Структура книга (поля: ФИО автора, название, издательство, год издания, число страниц). Создается массив книг размерности n. Сохраняется в файле и читается из файла. Файл открывается в двоичном режиме.

Для решения задач в среде Microsoft Visual Studio 2013 были созданы стандартные консольные приложения (проект типа Win32 Console Application) с установленным свойством «пустой проект» (Empty project). В каждый из проектов добавлен файл с расширением .cpp, исходные коды которых приведены ниже.

Листинг программы с комментариями для записи в файл:

#include <stdio.h>

#include <stdlib.h>

struct BOOK // Структура - книга

{

char Author[64];

char Title[128];

char Firm[64];

int year, page;

};

 

int main(int argc, char* argv[])

{

int n; // Переменная, задающая число элементов массива

BOOK *pBook; // Указатель на массив структур

printf("n="); scanf_s("%d", &n); // Ввод числа книг

pBook = new BOOK[n]; // Выделяем память под массив структур (книг)

for (int i = 0; i<n; i++) // Цикл ввода данных о книгах с клавиатуры

{

printf("Book N=%d:\n", i + 1);

printf("Author: ");

fflush(stdin); gets_s(pBook[i].Author, 63);

printf("Title: ");

fflush(stdin); gets_s(pBook[i].Title, 127);

printf("Firm: ");

fflush(stdin); gets_s(pBook[i].Firm, 63);

printf("year: "); scanf_s("%d", &pBook[i].year);

printf("page: "); scanf_s("%d", &pBook[i].page);

}

FILE *pF;

fopen_s(&pF, "MyBook.dat", "wb"); // Открываем файл для записи в двоичном режиме

fwrite(&n, sizeof(int), 1, pF); // Записываем в файл число элементов массива

fwrite(pBook, sizeof(BOOK), n, pF); // Записываем в файл массив книг

fclose(pF); // Закрываем файл

system("pause"); // Останавливаем программу, ждем нажатия любой клавиши

return 0;

}

 

Листинг программы с комментариями для чтения из файла:

#include <stdio.h>

#include <stdlib.h>

struct BOOK // Структура - книга

{

char Author[64];

char Title[128];

char Firm[64];

int year, page;

};

 

int main(int argc, char* argv[])

{

int n; // Переменная, задающая число элементов массива

BOOK *pBook; // Указатель на массив структур

FILE *pF;

fopen_s(&pF, "MyBook.dat", "rb");// Открываем файл для чтения в двоичном режиме

 

if (pF == 0) // Ошибка открытия файла, например, файл не существует

{

printf("Error, file not found");

return 1;

}

fread(&n, sizeof(int), 1, pF); // Читаем из файла число элементов массива

pBook = new BOOK[n]; // Выделяем память под массив структур (книг)

fread(pBook, sizeof(BOOK), n, pF); // Читаем из файла массив книг

fclose(pF); // Закрываем файл

for (int i = 0; i<n; i++) // Цикл вывода данных о книгах на экран

printf("%s. %s. %s, %d. - %d.\n", pBook[i].Author,

pBook[i].Title, pBook[i].Firm, pBook[i].year,

pBook[i].page);

system("pause"); // Останавливаем программу до нажатия любой клавиши

return 0;

}