Если файл открыт в бинарном режиме, его можно записывать или считывать побайтно. Функция fseek() позволяет обращаться с файлом как с массивом и переходить к любой позиции в файле, обеспечивая возможность произвольного доступа. Если текстовые файлы являются файлами с последовательным доступом, то произвольный доступ чаще всего применяется к бинарным файлам.
Бинарные файлы могут содержать любую информацию. Чаще всего используются файлы, содержащие структуры. Для чтения и записи в бинарные файлы можно использовать функции fread(), fwrite() или fscanf(),fprintf().
fread –функция для чтения из файла:
int fread(void *ptr, unsigned size, unsigned count, FILE *f);
Из файла f считываются и по адресу ptr записываются count элементов размером size каждый. Функция возвращает число фактически считанных элементов.
fwrite – функция для записи в файл:
int fwrite(void *ptr, unsigned size, unsigned count, FILE *f);
В файл записываются, начиная с адреса ptr, count элементов размером size каждый. Функция возвращает число фактически записанных элементов.
fseek – функция для произвольного доступа к байтам бинарных файлов:
int fseek(FILE *f, long offset, int w);
offset показывает, на сколько байт нужно сместиться относительно точки отсчёта – w.
w должно быть равно одной из трех констант:
SEEK_SET или 0 - начало файла;
SEEK_CUR или 1 – текущая позиция в файле;
SEEK_END или 2 – конец файла.
ftell - возвращает текущую позицию в файле как длинное целое:
long int ftell (FILE *f);
Пример обработки бинарного файла
Составить программу, выполняющую следующие функции:
Файл создать из структур вида: название товара, его цена и количество.
Задание выполнить в отдельных функциях. Использовать меню для выбора функций.
#include <stdio.h> #include <conio.h> #include <string.h> struct tov {char name[10]; float c; int kol;} t1; void input(FILE *); // создание нового файла void print(FILE *); // просмотр файла void app(FILE *); // добавление в файл void find(FILE *); // поиск и изменение main() { char c; FILE *tf; while (1) {clrscr(); puts(" 1 – новый файл"); puts(" 2 – просмотр файла"); puts(" 3 – добавление в файл"); puts(" 4 – поиск и изменение"); puts(" 0 - выход"); c=getch(); switch(c) { case '1':input(tf);break; case '2':print(tf);break; case '3':app(tf);break; case '4':find(tf);break; case '0':return 0; default : puts(" неверный режим"); } } } void input(FILE *tf) { char ch; tf=fopen("file1.dat","wb"); // открытие бинарного файла для записи clrscr(); printf("\n Ввод товаров\n"); do { printf("\n название: "); scanf("%s",t1.name); printf(" цена: "); scanf("%f",&t1.c); printf(" количество: "); scanf("%d",&t1.kol); fwrite(&t1,sizeof(t1),1,tf); // запись в файл одной структуры t1 printf("\n Закончить? y/n "); ch=getch(); } while (ch != 'y'); fclose(tf); } void print(FILE *tf) { int i; clrscr(); tf=fopen("file1.dat","rb"); // открытие бинарного файла для чтения i=1; fread(&t1,sizeof(t1),1,tf); // чтение из файла одной структуры t1 while (!feof(tf)) { printf("\n %3d tovar %10s cena %6.2f kolic %4d", i, t1.name, t1.c, t1.kol); fread(&t1,sizeof(t1),1,tf); i++; } getch(); } void app(FILE *tf) { char ch; tf=fopen("file1.dat","ab"); // открытие бинарного файла для добавления clrscr(); printf("\n Ввод товаров \n"); do { printf("\n название: "); scanf("%s", t1.name); printf(" цена: "); scanf("%f",&t1.c); printf(" количество: "); scanf("%d",&t1.kol); fwrite(&t1,sizeof(t1),1,tf); printf(" Закончить? y/n "); ch=getch(); } while (ch != 'y'); fclose(tf); } void find(FILE *tf) { char c, tov[10]; long int i; tf=fopen("file1.dat","rb+"); // открытие бинарного файла для чтения и записи clrscr(); puts(" Название искомого товара: "); gets(tov); fread(&t1,sizeof(t1),1,tf); while (!feof(tf)) { if (strcmp(t1.name,tov)==0) { printf(" tovar %10s cena %6.2f kolic %d",t1.name,t1.c,t1.kol); printf("\n изменить? y/n "); c=getch(); if (c=='y') { printf("\n количество: "); scanf("%d",&t1.kol); printf("\n цена: "); scanf("%f",&t1.c); i=sizeof(t1); fseek(tf, -i, 1); // возврат на sizeof(t1) байт назад fwrite(&t1,sizeof(t1),1,tf);//запись изменённой структуры } } fread(&t1,sizeof(t1),1,tf); } fclose(tf); }
1. Режимы доступа к файлам
2. Назначение функций fseek, ftell
3. Можно ли взаимозаменять функции fscanf и fread; fprintf и fwrite ?
4. Привести пример корректировки К-той записи в
файле прямого доступа.