Студопедия
Случайная страница | ТОМ-1 | ТОМ-2 | ТОМ-3
АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатика
ИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханика
ОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторика
СоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансы
ХимияЧерчениеЭкологияЭкономикаЭлектроника

Двоичные файлы

Читайте также:
  1. Беззнаковые двоичные коды.
  2. Виды ОС, их назначение и особенности. Файлы и файловая структура.
  3. Двоичные счетчики с последовательным
  4. Задание № 7. Файлы. Использование файлов для обработки и хранения данных.
  5. Знаковые дополнительные двоичные коды.
  6. Как восстановить зашифрованные вирусом файлы?

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

 

istream &get(char &ch);

 

ostream &put(char ch);

 

Функция get() читает единственный символ из ассоциированного потока и помещает его значение в ch. Она возвращает ссылку на поток. Функция put() пишет ch в поток и возвращает ссылку на этот поток.

Следующая программа использует функция put() для записи строки, содержащей не ASCII-символы.

 

Листинг 1

 

#include <iostream>

#include <fstream>

using namespace std;

 

int main()

{

char *p="hello there\n\r\xfe\xff";

 

ofstream out("test", ios::out|ios::binary);

if(!out) {

cout << "Cannot open file.\n";

return 1;

}

 

while(*p) out.put(*p++);

 

out.close();

 

return 0;

}

 

Второй способ чтения и записи двоичных данных состоит в использовании функций read() и write(). Наиболее обычный способ использования этих функций соответствует прототипу:

 

istream &read(unsigned char *buf, int num);

 

ostream &write(const unsigned char *buf, int num);

 

Функция read() читает num байт из ассоциированного потока и посылает их в буфер buf. Функция write() пишет num байт в ассоциированный поток из буфера buf.

Следующая программа пишет и потом читает массив целых чисел:

 

Листинг 2

 

#include <iostream>

#include <fstream>

using namespace std;

 

int main()

{

int n[5]={1, 2, 3, 4, 5};

register int i;

 

ofstream out("test", ios::out | ios::binary);

if(!out) {

cout << "Cannot open file.\n";

return 1;

}

 

out.write((const char *) &n, sizeof n);

out.close();

 

for (i=0; i<5; i++)

n[i]=0;

 

ifstream in("test", ios::in | ios::binary);

in.read((char *) &n, sizeof n);

 

for(i=0; i<5; i++)

cout << n[i] << " ";

 

in.close();

 

return 0;

}

 

Следует обратить внимание, что приведение типов в вызовах read() и write() необходимо для работы с буфером, который не определён как массив символов.

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

 

int gcount();

 

Она возвращает число символов, прочитанных последним оператором двоичного ввода.

 

Произвольный доступ

 

Система ввода-вывода С++ позволяет осуществлять произвольный доступ с использованием функции seekg() и seekp(). Их наиболее употребительной формой является следующая:

 

istream &seekg(streamoff offset, seek_dir origin);

 

ostream &seekp(streamoff offset, seek_dir origin);

 

Здесь тип streamoff определен в заголовочном файле iostream. Он определяет область значений, которые может принимать величина offset. В настоящее время streamoff определён как long.

Система ввода-вывода С++ обрабатывает два указателя, ассоциированные с каждым файлом. Один из них, get pointer, определяет, где именно в файле будет производиться следующая операция ввода. Другой указатель put pointer указывает, где именно в файле будет производиться следующая операция вывода. Всякий раз, когда осуществляются операции ввода или вывода, соответствующий указатель автоматически перемещается.

Функция seekg() перемещает указатель get pointer на offset байт от заданного origin, принимающего одно из следующих трех значений:

 

Величина Значение
ios::beg Начало файла
ios::cur Текущее положение
ios::end Конец файла

 

Функция seekp() перемещает указатель put pointer на offset байт от заданного origin, в качестве которого служит одно из указанных выше значений.

Можно определить текущую позицию файлового указателя, используя следующие функции:

 

streampos tellg();

 

streampos tellp();

 

Здесь тип streampos определён в заголовочном файле iostream. В текущей версии он определён как long.

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

 

Листинг 3

 

#include <iostream>

#include <fstream>

using namespace std;

 

class complexx{

double a;

double b;

public:

complexx(){ a=0; b=0; }

complexx(double i, double j);

double Re();

double Im();

complexx operator+(complexx c);

complexx operator*(complexx c);

friend ofstream &operator<<(ofstream &stream,complexx &c);

friend ifstream &operator>>(ifstream &stream,complexx &c);

};

 

complexx::complexx(double i, double j)

{

a=i;

b=j;

}

 

double complexx::Re()

{

return a;

}

 

double complexx::Im()

{

return b;

}

 

complexx complexx::operator+(complexx c)

{

complexx temp(0,0);

temp.a=a+c.a;

temp.b=b+c.b;

return temp;

}

 

complexx complexx::operator*(complexx c)

{

complexx temp(0,0);

temp.a=(a*c.a)-(b*c.b);

temp.b=(b*c.a)+(a*c.b);

return temp;

}

 

ofstream &operator<<(ofstream &stream,complexx &c)

{

stream.write((const char *)&c, sizeof complexx);

return stream;

}

 

ifstream &operator>>(ifstream &stream,complexx &c)

{

stream.read((char *)&c, sizeof complexx);

return stream;

}

 

int main()

{

complexx a(0, 1), b(1, 0), c(0,0);

c=a*a;

cout << "Multiplay a, b\n";

cout << c.Re() << " "<< c.Im() << "\n";

c=a+b;

cout << "Add a, b\n";

cout << c.Re() << " " << c.Im() << "\n";

 

ofstream out("test.bin",ios_base::binary|ios_base::out);

cout << "File is opening" << endl;

for(unsigned int i=0; i<10; i++) out<<c;

out.close();

cout << "Zapisano in file.\n";

complexx d(0,0);

 

ifstream in("test.bin",ios::binary|ios::in);

 

unsigned int n;

 

in.seekg(0,ios::end);

n=in.tellg();

 

cout<< "Schitano " << n/(sizeof complexx) << " objects of class complexx\n";

 

complexx *array = new complexx[(n/(sizeof complexx))];

 

in.seekg(0,ios::beg);

 

unsigned int i;

for(i=0; i<(n/(sizeof complexx)); i++) in>>array[i];

 

in.close();

 

cout<<"Massiv \n";

for (i=0; i<(n/(sizeof complexx)); i++)

cout<<i<<" "<< d.Re() << " " << d.Im() << "\n";

 

return 0;

}

 

Варианты заданий

 

Номер рабочего места     Задание
1, 7, 13, 19, 25 Подстановка множества – взаимно однозначное отображение множества на себя. В случае отображения конечного множества Х на себя удобно считать, что Х={1, 2, …, n}, и записывать подстановку в виде   , (*) где - некоторая перестановка чисел 1, 2, …, n. Запись (*) означает, что g переводит число k в ik, то есть g(k)= ik. Произведение подстановок a и b определяется как последовательное выполнение отображений a и b и задаются формулой ab(х)= b(a(х)). Создать класс в ортодоксальной канонической форме – подстановка степени 5. В класс включить конструктор, задающий подстановку путем передачи ему нижней строки подстановки. Конструктор должен выдавать сообщение в случае неверно введенных данных. В класс включить функцию, выводящую подстановку на консоль и функцию, выводящую результат действия подстановки на числа от 1 до 5. Перегрузить оператор * так, чтобы он выполнял операцию умножения подстановок. Функции при получении некорректных аргументов должны выдавать предупреждение. Перегрузить операторы вставки в поток и извлечения из потока так, чтобы они извлекали и вставляли объекты класса в потоки, ассоциированные с двоичными файлами. Написать две программы. Первая - создает заданное пользователем количество объектов класса «подстановка 5 степени» и записывает их в новый двоичный файл без разделителей. Вторая программа получает двоичный файл, в котором записаны объекты без разделителей. Программа должна записывать новый двоичный файл, в начале файла должен содержаться объект, отображающий подстановку равную произведению всех подстановок, которым соответствуют объекты в файле. Дальше без разделителей должны содержаться объекты из исходного файла, записанные в обратном порядке.
2, 8, 14, 20, 26 Создать класс в ортодоксальной канонической форме, отображающий материальную точку на плоскости. Материальная точка должна иметь координаты, массу и вектор скорости. В классе должны быть функции-члены: 1. конструктор, имеющий аргументы: массу, начальное значение координат и вектора скорости; 2. изменяющая значение координат и вектора скорости под действием силы (её вектор – первые аргументы функции) в течение указанного времени (третий аргумент); 3. выводящая на экран значения координат и вектора скорости. Функции при получении некорректных аргументов должны выдавать предупреждение. Перегрузить операторы вставки в поток и извлечения из потока так, чтобы они извлекали и вставляли объекты класса в потоки, ассоциированные с двоичными файлами. Написать две программы. Первая - создает заданное пользователем количество объектов класса «материальная точка» и записывает их в новый двоичный файл без разделителей. Вторая программа получает двоичный файл, в котором записаны объекты без разделителей. Считаем, что эти материальные точки задают систему материальных точек. Вторая программа должна записывать новый двоичный файл, в начале файла должен содержаться объект, масса которого равна массе системы, координаты – координатам центра масс системы, вектор скорости – вектору скорости движения центра масс. Дальше без разделителей должны содержаться объекты из исходного файла, записанные в обратном порядке.
3, 9, 15, 21, 27 Создать класс в ортодоксальной канонической форме, отображающий механический счётчик. Счётчик может принимать значения от 0 до 999. У счетчика есть две кнопки – «+» и «с». При нажатии кнопки «+» счётчик переходит в следующее состояние: - если его значение от 0 до 998, то значение увеличится на единицу; - если его значение 999, то его значение станет равным 0. При нажатии кнопки «с» значение счетчика становится равным 0. В классе должны быть функции-члены: 1. конструктор, имеющий аргумент – начальное значение; 2. функция, моделирующая нажатие кнопки «+»; 3. функция, моделирующая нажатие кнопки «с»; 4. функция, возвращающая значение счётчика. Функции при получении некорректных аргументов должны выдавать предупреждение. Перегрузить операторы вставки в поток и извлечения из потока так, чтобы они извлекали и вставляли объекты класса в потоки, ассоциированные с двоичными файлами. Написать две программы. Первая - создает заданное пользователем количество объектов класса «счетчик» и записывает их в новый двоичный файл без разделителей. Вторая программа получает двоичный файл, в котором записаны объекты без разделителей. Вторая программа должна записывать новый двоичный файл, содержащий те же объекты без разделителей, в середине файла поместить объект, состояние которого равно остатку от деления на 1000 суммы значений объектов.
4, 10, 16, 22, 28 Создать класс в ортодоксальной канонической форме, отображающий твёрдое тело имеющее массу, температуру по Кельвину и теплоёмкость. В классе должны быть функции-члены: 1. конструктор, имеющий аргументы – массу, начальное значение температуры, удельная теплоёмкость, 2. функция, изменяющая значение температуры при получении телом определённого количества тепла (количество тепла – аргумент функции), 3. функция, изменяющая значение температуры при отборе у тела определённого количества тепла (количество тепла – аргумент функции), 4. функция, возвращающая температуру тела. Функции при получении некорректных аргументов должны выдавать предупреждение. Перегрузить операторы вставки в поток и извлечения из потока так, чтобы они извлекали и вставляли объекты класса в потоки, ассоциированные с двоичными файлами. Написать две программы. Первая - создает заданное пользователем количество объектов класса «твердое тело» и записывает их в новый двоичный файл без разделителей. Вторая программа получает двоичный файл, в котором записаны объекты без разделителей. Считаем, что эти тела образуют систему тел, в которой все тела соприкасаются между собой и система не обменивается энергией с внешней средой. Дописать в конец файла объект, масса которого равна сумме масс, температура – температуре, которая установится при обмене теплом между телами, теплоёмкость – средней теплоёмкости.
5, 11, 17, 23, 29 Создать класс в ортодоксальной канонической форме, отображающий водный бассейн. Бассейн должен иметь максимальный объём, начальный объем содержащейся воды. В классе должны быть функции-члены: 1. конструктор, устанавливающий значения максимального объёма и начального объёма воды, 2. функция, изменяющая значение содержащегося объёма воды при добавлении некоторого количества, аргумент функции – количество добавляемой воды (функция должна выдавать сообщение при переполнении бассейна), 3. функция, изменяющая значение содержащегося объёма воды при заборе некоторого количества, аргумент функции – количество забираемой воды (функция должна выдавать сообщение при опустошении бассейна), 4. функция, возвращающая объём содержащийся в бассейне воды. Функции при получении некорректных аргументов должны выдавать предупреждение. Перегрузить операторы вставки в поток и извлечения из потока так, чтобы они извлекали и вставляли объекты класса в потоки, ассоциированные с двоичными файлами. Написать две программы. Первая - создает заданное пользователем количество объектов класса «бассейн» и записывает их в новый двоичный файл без разделителей. Вторая программа получает двоичный файл, в котором записаны объекты без разделителей. Записать в середину файла объект – бассейн, максимальный объём которого равен сумме максимальных объёмов, начальный объём равен сумме начальных объёмов.
6, 12, 18, 24, 30 Создать класс в ортодоксальной канонической форме, отображающий часы. Класс должен содержать текущее значение времени – часы, минуты, секунды. В классе должны быть функции-члены: 1. конструктор, устанавливающий начальное значение времени, задаваемое аргументами – часы, минуты, секунды, 2. функция, изменяющая значение времени на 1 секунду вперёд, 3. функция, позволяющая установить нужное время, 4. функция, выводящая на экран время – часы, минуты, секунды. Функции при получении некорректных аргументов должны выдавать предупреждение. Перегрузить операторы вставки в поток и извлечения из потока так, чтобы они извлекали и вставляли объекты класса в потоки, ассоциированные с двоичными файлами. Написать две программы. Первая - создает заданное пользователем количество объектов класса «часы» и записывает их в новый двоичный файл без разделителей. Вторая программа получает двоичный файл, в котором записаны объекты без разделителей. Записать в начало файла объект, содержащий минимальное значение показаний часов, в конец объект, содержащий максимальное значение показаний часов.

 


Дата добавления: 2015-08-09; просмотров: 114 | Нарушение авторских прав


Читайте в этой же книге: Методичні вказівки до розв’язування задач | Приклади розв’язування задач. | І РІВЕНЬ | ІІ РІВЕНЬ | ІІІ РІВЕНЬ |
<== предыдущая страница | следующая страница ==>
Понятие морального вреда в медицин­ской деятельности. Основания, способы и размер компенсации морально­го вреда при повреждении здоровья и причинении смерти пациенту.| Основні поняття і співвідношення

mybiblioteka.su - 2015-2024 год. (0.019 сек.)