Двоичные (бинарные) файлы. Блочно-ориентированный ввод-вывод. 


Мы поможем в написании ваших работ!



ЗНАЕТЕ ЛИ ВЫ?

Двоичные (бинарные) файлы. Блочно-ориентированный ввод-вывод.



 

 

Важнейшими функциями блочно-ориентированного ввода-вывода являются fread() и fwrite(), которые обеспечивают соответственно чтение из файла и запись в файл заданного количества блоков данных фиксированной длины. Блок (запись) –группа подряд расположенных байтов, не имеющая никаких специальных разделителей. За одно обращение к таким функциям переносится n блоков длиной size байтов каждый. Никакого преобразования данных при этом не происходит. Такие файлы следует открывать в двоичном режиме для подавления преобразования символа перехода на следующую строку.

Пример:

FILE *fp; fp=fopen(namein, "rb");

 

Чтение данных из файла осуществляет функция fread().

Прототип:

 

int fread(void *_ptr, unsigned size, int n, FILE *_fp);

 

Описание:

Функция fread() считывает n элементов данных, каждый длиной size байтов, из потока _fp. Считанные данные помещаются в область памяти, на которую ссылается указатель _ptr. Общее число вводимых байт равно n * size.

 

Возвращаемое значение:

При успешном завершении функция возвращает количество реально прочитанных блоков данных (не байт). В случае достижения конца файла или возникновения ошибки функция fread() возвращает EOF.

 

Запись данных в файл осуществляет функция fwrite().

Прототип:

 

int fwrite (void *_ptr, unsigned size, int n, FILE *_fp);

 

Описание:

Функция fwrite()добавляетв открытый поток, связанный с файловой переменной _fp, n блоков данных размером size байтов каждый. Данные записываются из области памяти, определяемой указателем _ptr. Общее число выведенных байт равно n*size.

 

Возвращаемое значение:

При успешном завершении fwrite() возвращает число выведенных блоков (не байт). При ошибке она возвращает меньшее число.


Задача 166. Программа создает на диске файл – каталог книг вашей библиотеки. Каждая запись файла содержит поля:

- инвентарный номер;

- автор;

- название книги;

- издательство;

- год издания

 

// ktlg_gut_2013.cpp: Для Visual Studio.NET 2010 26 апр. 2013

// Создание файла-каталога книг Вашей библиотеки исп fread fwrite

#include "stdafx.h"

#include <stdio.h>

#include <conio.h>

#include <iostream>

using namespace std;

#define LIM 50 // макс число книг

int main()

{ struct book

{ int inv_nom; //инв. номер

char avtor[15]; //автор

char title[20]; //название

char izdat[15]; //издательство

int year; //год издания

};

book zap; int k=0; char ch; FILE *inout;

int size=sizeof(struct book); //размер структуры

system("chcp 1251"); //переключаем консоль в кодировку win1251

// ОБЯЗАТЕЛЬНО ПЕРЕКЛЮЧИТЬ ШРИФТЫ С ТОЧЕЧНЫХ НА Lucida console

// после запуска программы щелчком мыши в левом

// верхнем углу программы -> Свойства

 

// создание файла или добавление записей в существующий файл

system("cls"); system("color 1E");

cout<<"\n\tСоздание файла-каталога книг Вашей библиотеки\n\n";

inout=fopen("D:\\catalog.str", "a+b");

if(inout==NULL)

{

puts(" Не могу открыть вводной/выводной файл... ");

_getch();exit(1);

}

/*

do

{

cout<<"\nВведи "<<k+1<<" -ю запись:\n";

cout<<"Фамилия автора - "; gets(zap.avtor);

cout<<"название книги - "; gets(zap.title);

cout<<"издательство - "; gets(zap.izdat);

cout<<"год издания - "; cin>>zap.year;

k++;

fflush(stdin); //очистить входной поток

//************************************

fwrite(&zap,size,1,inout);

//************************************

cout<<" \n\n\n Будем продолжать (Y/N)? ";

ch=_getch();

}

while(ch=='Y'||ch=='y'||ch=='Н'||ch=='н');

*/

 

//Более изящный ввод структур против предыдущего

cout<< "\nВведи до "<<LIM<<" книг"<<'\n';

cout<< "Для прекращения - Enter в начале строки"<<'\n';

// новые записи добавляются в конец файла

cout<< "Фамилия "<<k+1<<" -го автора - ";

while((gets(zap.avtor)!=NULL)&&

(zap.avtor[0])!='\0' && k<LIM)

{

cout<< "название книги - "; gets(zap.title);

cout<< "издательство - "; gets(zap.izdat);

cout<< "год издания - "; cin>>zap.year;

k++;

//************************************

fwrite(&zap,size,1,inout);

//************************************

if(k<LIM)

cout<< "Фамилия "<<k+1<<" -го автора - "; fflush(stdin);

}

 

cout<< "\n\n\n\tКаталог книг моей библиотеки\n\n";

rewind(inout); // в начало файла

 

// за 1 раз считываем 1 структуру

while(fread(&zap, sizeof(book), 1, inout)==1)

{

printf("\n%-15s %-20s %-15s %10d \n",

zap.avtor, zap.title, zap.izdat, zap.year);

}

fclose(inout); puts("\n\nКонец"); _getch();

return 0;

}

 

Задача 167. Программа выполняет поиск записи с заданным полем avtor в ранее созданном бинарном файле, содержащем сведения о книгах домашней библиотеки. Реализована обработка неудачного поиска.

// find_fio_2013.cpp: Программа отлажена в Visual Studio 2010

// Выделение подфамилии - функция strstr()

 

#include "stdafx.h"

#include <stdio.h>

#include <conio.h>

#include <iostream>

using namespace std;

#define LIM 50 // макс число книг

 

struct book //book - имя нового типа!

{ int inv_nom; //инв. номер

char avtor[15]; //автор

char title[20]; //название

char izdat[15]; //издательство

int year; //год издания

};

FILE *inout;

 

int main()

{

char ch, fio[20]; char namein[20]="D:\\catalog.str";

//переключаем консоль в кодировку win1251

system("chcp 1251");

if((inout=fopen(namein, "r+b"))==NULL)

{

cout<<" Не могу открыть файл... ";

getch();exit(1);

}

 

struct book zap; // структура типа book

//int size=sizeof(struct book);

 

do

{ rewind(inout);

 

// за 1 раз считываем 1 структуру

int k=0, flag=0;

cout<<"\nВведи фамилию для поиска ==>";

gets(fio);

 

while(fread(&zap, sizeof(book), 1, inout)==1)

{

if(strstr(zap.avtor,fio))

if(zap.avtor[strlen(fio)]==' ') //fio завершается пробелом?

{

cout<<"\nНайдена запись "<<++k;

 

printf("\n%-15s %-20s %-15s %10d \n",

zap.avtor, zap.title, zap.izdat, zap.year);

 

flag=1;

}

} //конец while

if(flag==0)

cout<<"\nЗапись с фамилией "<<fio<<" не найдена...";

 

cout<<"\n Продолжать (Y/N)? ";

ch = getch();

}

while(ch=='Y'||ch=='y'||ch=='Н'||ch=='н');

 

wcout<<"\nПока...Жми Enter";

fclose(inout);

_getch();return 0;

}

 



Поделиться:


Последнее изменение этой страницы: 2016-12-16; просмотров: 330; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 18.217.220.114 (0.024 с.)