История развития хранилищ для нефти: Первые склады нефти появились в XVII веке. Они представляли собой землянные ямы-амбара глубиной 4…5 м...
Опора деревянной одностоечной и способы укрепление угловых опор: Опоры ВЛ - конструкции, предназначенные для поддерживания проводов на необходимой высоте над землей, водой...
Топ:
Теоретическая значимость работы: Описание теоретической значимости (ценности) результатов исследования должно присутствовать во введении...
Эволюция кровеносной системы позвоночных животных: Биологическая эволюция – необратимый процесс исторического развития живой природы...
Организация стока поверхностных вод: Наибольшее количество влаги на земном шаре испаряется с поверхности морей и океанов...
Интересное:
Аура как энергетическое поле: многослойную ауру человека можно представить себе подобным...
Отражение на счетах бухгалтерского учета процесса приобретения: Процесс заготовления представляет систему экономических событий, включающих приобретение организацией у поставщиков сырья...
Подходы к решению темы фильма: Существует три основных типа исторического фильма, имеющих между собой много общего...
Дисциплины:
2022-02-10 | 62 |
5.00
из
|
Заказать работу |
2.9.1. Функции для работы с двоичными файлами
При записи информации в двоичный файл символы и числа преобразуются в последовательность из байтов.
Для того чтобы записать данные в двоичный файл, необходимо:
Для того чтобы считать данные из двоичного файла, необходимо:
Рассмотрим основные функции, необходимые для работы с двоичными файлами.
Для открытия файла в зависимости от используемых библиотек используются функции fopen или fopen_ s. В них последним параметром является mode - строка, определяющая режим работы с файлом; возможны следующие ее значения:
Для закрытия файла предназначена функция fclose
intfclose(FILE *filename);
Возвращает 0 при успешном закрытие файла и NULL в противном случае. Функция remove предназначена для удаления файлов.
intremove(constchar *filename);
Эта функция удаляет с диска файл с именем filenаmе. Удаляемый файл должен быть закрыт. Функция возвращает ненулевое значение, если файл не удалось удалить.
Для переименования файлов предназначена функция rename:
int rename(const char *oldfilename, const char *newfilename);
Первый параметр — старое имя файла, второй — новое. Возвращает 0 при удачном завершении программы.
Чтение из двоичного файла осуществляется с помощью функции fread:
fread(void *ptr, size, n, FILE *filename);
Функция fread считывает из файла filename в массив ptr n элементов размера size. Функция возвращает количество считанных элементов. После чтения из файла его указатель смещается на n*size байт.
Запись в двоичный файл осуществляется с помощью функции fwrite:
fwrite(const void *ptr, size, n, FILE *filename);
Функция fwrite записывает в файл filename из массива ptr n элементов размера size. Функция возвращает количество записанных элементов. После записи информации в файл указатель смещается на n*size байт.
Для контроля достижения конца файла есть функция feof:
intfeof(FILE *filename);
Она возвращает ненулевое значение если достигнут конец файла.
При записи информации в двоичный файл символы и числа преобразуются в последовательность из байтов.
Для закрытия файла предназначена функция fclose
intfclose(FILE *filename);
Возвращает 0 при успешном закрытие файла и NULL в противном случае. Функция remove предназначена для удаления файлов.
intremove(constchar *filename);
Эта функция удаляет с диска файл с именем filenаmе. Удаляемый файл должен быть закрыт. Функция возвращает ненулевое значение, если файл не удалось удалить.
Для переименования файлов предназначена функция rename:
int rename(const char *oldfilename, const char *newfilename);
Первый параметр — старое имя файла, второй — новое. Возвращает 0 при удачном завершении программы.
Чтение из двоичного файла осуществляется с помощью функции fread:
fread(void *ptr, size, n, FILE *filename);
Функция fread считывает из файла filename в массив ptr n элементов размера size. Функция возвращает количество считанных элементов. После чтения из файла его указатель смещается на n*size байт.
Запись в двоичный файл осуществляется с помощью функции fwrite:
fwrite(const void *ptr, size, n, FILE *filename);
Функция fwrite записывает в файл filename из массива ptr n элементов размера size. Функция возвращает количество записанных элементов. После записи информации в файл указатель смещается на n*size байт.
Для контроля достижения конца файла есть функция feof:
intfeof(FILE *filename);
Она возвращает ненулевое значение если достигнут конец файла.
2.9.2. Просмотр содержимого двоичных файлов
Для просмотра содержимого двоичных (бинарных) файлов необходимы специальные программы. Обычно они представляют двоичную байтовую информацию в шестнадцатеричной системе счисления. В ней каждый байт, состоящий из 8 бит, разбивается на две тетрады (части по 4 бита), которые заменяются одной шестнадцатеричной цифрой по правилу:
1. 00002 - 016; 8) 10002 - 816;
2. 00012 - 116; 9) 10012 - 916;
3. 00102 - 216; 10) 10102 - A16;
4. 00112 - 316; 11) 10112 - B16;
5. 01002 - 416; 12) 11002 - C16;
6. 01012 - 516; 13) 11012 - D16;
7. 01102 - 616; 14) 11102 - E16;
8. 01112 - 716; 15) 11112 - F16.
Для записи целых шестнадцатеричных чисел в отдельные байты в языке С++ используется шестнадцатеричная форма записи, начинающаяся с Ох. Например, после присваиваний:
chars1,s2
s1=OxAB;
s2=Ox2F;
в байтах s1 и s2 будут содержаться шестнадцатеричные числа AB16 и 2F16, которые соответствуют двоичным словам 101010112 и 001011112.
Шестнадцатеричная система счисления позволяет непосредственно записывать двоичные числа в байты. Например, если в байт s1 необходимо записать последовательность значений 8 бит, равную 101011002, то сначала эта последовательность разбивается на две тетрады (10102 и 11002), они переводятся в соответствующие шестнадцатеричные числа (А16 и C16), а затем выполняется присваивание:
s1=OxAC;
Для считывания отдельных байтов (в переменную типа char) с игнорированием пробелов можно использовать создание потока и обычны й потоковый вывод.
Пример 1. Написать функцию prf(stringf) для вывода на экран содержимого каждого байта файла с именем f в виде символа, шестнадцатеричного числа и двоичного числа. Между выводимыми числами поставить знак “=” (равенство).Для примера вывести на экран содержимое бинарного файла C:\\TEXT\\d.dat.
Решение:
#include "stdafx.h"
#include <iostream>
#include <fstream>
#include <iomanip>
#include <stdlib.h>
#include <string>
using namespace std;
void prf(string f);
void main(){
string p;
p="C:\\TEXT\\d.dat";
prf(p);
}
void prf(string f) {
setlocale (LC_ALL, "RUS");
unsigned int n, i,j,b,b2,st,fc,sc;
unsigned char G[16] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
unsigned int *d = new unsigned int [8];
unsigned char *a;
char ch, F, S;
fstreampf;
pf.open(f);//открываем файл в режиме чтения
a=newunsignedchar[1000]; //выделение памяти для буферного массива а
i=0;
while (!pf.eof()){ //запись содержимого файла в буферный массив а
pf>>ch;
a[i]=(unsigned int)ch;
i+=1; //чтение очередного байта из файла в массив a
};
n=i-1;
for (i=0; i<n; i++) {
cout<<a[i]<<"=";//выводсимвола a[i] наэкран
b=(int)a[i]; //перевод символа в целочисленное представление
fc=b/16; sc=b-fc*16; F = G[fc]; S = G[sc];//перевод символа в 16-ричный вид
cout<<F<<S<<"=";//вывод 16-ричной кодировки символа a[i] на экран
for (j=0; j<8; j++) { b2=b/2; d[j]= b-2*b2; b=b2; };//перевод символа в двоичный вид
cout<<d[7]<<d[6]<<d[5]<<d[4]<<d[3]<<d[2]<<d[1]<<d[0];//вывод 2-чной кодировки символа a[i] на экран
cout<<endl; // переход на новую строку
};
pf.close(); //закрываемфайл
system("pause");
}
2.9.3. Чтение и запись в двоичные файлы
Для считывания всех подряд байтов (в том числе - пустых) можно использовать функцию fscanf_s.
Пример 2. Написать функцию prfp(char * name)для вывода на экран содержимого каждого байта файла с заданным именем в виде символа, шестнадцатеричного числа и двоичного числа. Между выводимыми числами поставить знак “=” (равенство).Для примера вывести на экран содержимое бинарного файла C:\\TEXT\\d.dat.
#include "stdafx.h"
#include <iostream>
#include <fstream>
#include <iomanip>
#include <stdlib.h>
#include <string>
using namespace std;
void prfp(char * name);
void main(){
char * fileName = "C:\\TEXT\\d.dat";
prf(fileName);
}
void prfp(char * name) {
setlocale (LC_ALL, "RUS");
int n, i,j,b,b2,fc,sc;
unsigned char G[16] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
unsigned int *d = new unsigned int [8];
unsigned char a;
unsigned char F, S;
FILE *f;
char c;
char *mc;
mc = new char[1000];
int err=fopen_s(&f, name, "r");
if(err){return;};
cout<<"FILE = ";
i=-1;
while(fscanf_s(f,"%c",&c,1)==1) {
i=i+1; printf("%c",c); mc[i]=c;
};
n=i+1;
cout<<endl;
for (i=0; i<n; i++) {
cout<<mc[i]<<"=";//вывод символа a[i] на экран
a = (unsigned char)mc[i];
b=(int)a; //перевод символа в целочисленное представление
fc=b/16; sc=b-fc*16;
//cout<<"fc="<<fc<<"sc="<<sc;
F = G[fc]; S = G[sc];//перевод символа в 16-ричный вид
cout<<F<<S<<"=";//вывод 16-ричной кодировки символа a[i] на экран
for (j=0; j<8; j++) { b2=b/2; d[j]= b-2*b2; b=b2; };//перевод символа в двоичный вид
cout<<d[7]<<d[6]<<d[5]<<d[4]<<d[3]<<d[2]<<d[1]<<d[0];//вывод 2-чной кодировки символа a[i] на экран
cout<<endl; // переход на новую строку
};
fclose(f);
system("pause");
}
Рассмотрим примеры записи и чтения содержимого двоичных файлов.
Пример 3. Создать двоичный файл D:\\str.dat, записать в него вводимое с клавиатуры целое число n, а затем - n вводимых с клавиатуры вещественных чисел.
Решение:
#include "stdafx.h"
#include <iostream>
using namespace std;
void main() {
setlocale (LC_ALL, "RUS");
int n, i;
doublea;
FILE *f; // описываем файловую переменную
fopen_s(&f,"D:\\str.dat", "wb");// создаем двоичный файл в режиме записи
cout<<"n="; cin>>n; //вводчисла n
fwrite(&n, sizeof(int), 1, f); // запись целого числаn в файл
for (i=0; i<n; i++) { // цикл для ввода c клавиатуры в файл n вещественных чисел
cout<<"a=";// вывод на экран запроса на ввод очередного веществен.числа
cin>>a; // вводочередного вещественного числа с клавиатуры
fwrite(&a, sizeof(double), 1, f); // запись вещественного числа в двоичный файл
}
fclose(f); // закрываемфайл
system("pause");
}
Пример 4. Вывести на экран содержимое созданного в прошлой задаче двоичного
файлаD:\\ str. datв виде вещественных чисел.
Решение:
|
Создать двоичный файл D:\\game\\noobs.dat и записать в него целое число n и n вещественных чисел.
Решение:
#include "stdafx.h" #include <iostream> usingnamespacestd; int main() { setlocale(LC_ALL, "RUS"); int n, i; double a; FILE*f;//описываемфайловуюпеременную //создаемдвоичныйфайлврежимезаписи f=fopen("D:\\game\\noobs.dat", "wb"); //вводчисла n cout<<"n=";cin>>n; fwrite(&n, sizeof(int), 1, f); //циклдлявводаnвещественныхчисел for(i=0;i<n;i++) { //вводочередноговещественногочисла cout<<"a="; cin>>a; //записьвешественногочиславдвоичныйфайл fwrite(&a, sizeof(double), 1, f); } //закрываемфайл fclose(f); system("pause"); return0; } |
Пример 2. Вывести на экран содержимого созданного в прошлой задаче двоичного файла D:\\game\\noobs.dat
Решение:
#include "stdafx.h" #include <iostream> usingnamespacestd; int main() { setlocale(LC_ALL, "RUS"); int n, i; double*a; FILE*f;//описываем файловую переменную //открываем существующий двоичный файл в режиме чтения f=fopen("D:\\game\\noobs.dat", "rb"); //считываем из файла одно целое число в переменную n fread(&n, sizeof(int), 1, f); //вывод n на экран cout<<"n="<<n<<endl; //выделение памяти для массива из n чисел a=newdouble[n]; //чтение n вещественных чисел из файла в массив a fread(a, sizeof(double), n, f); //выводмассиванаэкран for(i=0;i<n;i++) cout<<a[i]<<"\t"; cout<<endl; fclose(f);//закрываемфайл system("pause"); return0; } |
Двоичный файл — последовательная структура данных, после открытия файла доступен первый байт, хранящийся в нем. Можно последовательно записывать или считывать данные из файла.
Пример 3. Требуется считать пятнадцатое число, а затем первое.
Решение. С помощью последовательного доступа это можно сделать следующим способом:
1 2 3 4 5 6 7 8 9 10 | int n, i; double a; FILE*f; f=fopen("D:\\game\\noobs.dat", "rb"); for(i=0; i<15; i++) fread(&a, sizeof(double), 1, f); fclose(f); f=fopen("D:\\game\\noobs.dat", "rb"); fread(&a, sizeof(double), 1, f); fclose(f); |
Последовательное чтение чисел из файла, а затем повторное открытие файла — не самый удобный способ извлечения информации из него. Гораздо удобнее использовать функцию fseek перемещения указателя файла к заданному байту.
intfseek(FILE *filename, long int offset, int origin);
Функция устанавливает указатель текущий позиции файла F в соответствии со значением начала отсчета origin и смещения offset. Параметр offset равен количеству байтов, на которые будет смещен указатель файла относительно начала отсчета, заданного параметром origin. В качестве значения для параметра origin должно быть взято одно из следующих значений отсчета смещения offset, определенных в заголовке stdio.h:
Функция возвращает нулевое значение при успешном выполнение операции, ненулевое — при возникновении сбоя при выполнении смещения
Функция fseek фактически реализует прямой доступ к любому значению в файле. Необходимо только знать месторасположение (номер байта) значения в файле. Пример 4. В созданном ранее двоичном файле D:\\game\\noobs.dat, поменять местами наибольшее и наименьшее из вещественных чисел.
Решение. Алгоритм решения задачи состоит из следующих этапов:
1. чтение вещественных из файла в массив a.
2. поиск в массиве а максимального (max) и минимального (min) значения и их номеров (imax, imin).
3. перемещения указателя файла к максимальному значению и запись min.
4. перемещения указателя файла к минимальному значению и запись max.
Текст программы решения задачи с комментариями.
#include "stdafx.h" #include <iostream> usingnamespacestd; int main() { setlocale(LC_ALL, "RUS"); int n, i, imax, imin; double*a, max, min; FILE*f; //открытие файла в режиме чтения и записи f=fopen("D:\\game\\noobs.dat", "rb+"); //считываемизфайлавпеременнуюколичество //вещественныхчиселвфайле fread(&n, sizeof(int), 1, f); cout<<"n="<<n<<endl; //выделяемпамятьдляхранениявещественны чисел, //которыебудутхранитьсявмассивеa a=newdouble[n]; //считываемизфайлавмассивавещественныечисла fread(a, sizeof(double), n, f); //поискмаксимальногоиминимальногоэлементов //вмассивеаиихиндексов for(imax=imin=0, max=min=a[0], i=1; i<n; i++){ if(a[i]>max){max=a[i];imax=i;} if(a[i]<min){min=a[i];imin=i;}} //перемещениеуказателякмаксимальномуэлементу fseek(f, sizeof(int)+imax*sizeof(double), SEEK_SET); //записьminвместомаксимальногоэлементафайла fwrite(&min, sizeof(double), 1, f); //перемещениеуказателякминимальномуэлементу fseek(f, sizeof(int)+imin*sizeof(double), SEEK_SET); //записьmaxвместоминимальногоэлементафайла fwrite(&max, sizeof(double), 1, f); //закрытиефайла fclose(f); //освобождениепамяти delete[]a; system("pause");return0; } |
Семя – орган полового размножения и расселения растений: наружи у семян имеется плотный покров – кожура...
Механическое удерживание земляных масс: Механическое удерживание земляных масс на склоне обеспечивают контрфорсными сооружениями различных конструкций...
Архитектура электронного правительства: Единая архитектура – это методологический подход при создании системы управления государства, который строится...
Индивидуальные очистные сооружения: К классу индивидуальных очистных сооружений относят сооружения, пропускная способность которых...
© cyberpedia.su 2017-2024 - Не является автором материалов. Исключительное право сохранено за автором текста.
Если вы не хотите, чтобы данный материал был у нас на сайте, перейдите по ссылке: Нарушение авторских прав. Мы поможем в написании вашей работы!