Программирование на языках высокого уровня. Язык программирования Си 

 

назад | оглавление | вперёд

 

10. Обработка бинарных файлов

10.1. Основные понятия

Если файл открыт в бинарном режиме, его можно записывать или считывать побайтно. Функция 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);

 

Пример обработки бинарного файла

Составить программу, выполняющую следующие функции:

    1. Создание нового файла;
    2. Просмотр файла;
    3. Добавление информации в конец файла;
    4. Поиск по названию товара и изменение цены и количества;

Файл создать из структур вида: название товара, его цена и количество.

Задание выполнить в отдельных функциях. Использовать меню для выбора функций.

 

#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);

}

 

 

10.2. Контрольные вопросы

10.2.1. Режимы доступа к файлам

10.2.2. Назначение функций fseek, ftell

10.2.3. Можно ли взаимозаменять функции fscanf и fread; fprintf и fwrite ?

10.2.4. Привести пример корректировки К-той записи в файле прямого доступа.


назад | оглавление | вперёд