АвтоАвтоматизацияАрхитектураАстрономияАудитБиологияБухгалтерияВоенное делоГенетикаГеографияГеологияГосударствоДомДругоеЖурналистика и СМИИзобретательствоИностранные языкиИнформатикаИскусствоИсторияКомпьютерыКулинарияКультураЛексикологияЛитератураЛогикаМаркетингМатематикаМашиностроениеМедицинаМенеджментМеталлы и СваркаМеханикаМузыкаНаселениеОбразованиеОхрана безопасности жизниОхрана ТрудаПедагогикаПолитикаПравоПриборостроениеПрограммированиеПроизводствоПромышленностьПсихологияРадиоРегилияСвязьСоциологияСпортСтандартизацияСтроительствоТехнологииТорговляТуризмФизикаФизиологияФилософияФинансыХимияХозяйствоЦеннообразованиеЧерчениеЭкологияЭконометрикаЭкономикаЭлектроникаЮриспунденкция

Двоичный (бинарный) ввод/вывод. Объектный ввод/вывод (запись объектов в файл и чтение объектов из файла)

Читайте также:
  1. Анализ окружения объектов недвижимости
  2. Анимация объектов презентации
  3. Бухгалтерский учет объектов интеллектуальной собственности в составе нематериальных активов предприятия
  4. Ввод/вывод аналоговых сигналов
  5. Виды организаций – участников реализации капитальных вложений в строительство объектов
  6. Внедрение и связывание объектов
  7. Вопрос –2 Муниципально-правовые отношения. Виды и особенности субъектов, объектов и содержания м-п отношений.
  8. Восстановление нечитаемых записей, разорванных и сожженных документов, прочтение шифровальной переписки
  9. Восстановление удаленных объектов.
  10. Вставка объектов на слайд
  11. Выделение (пометка) объектов
  12. Выделение (пометка) объектов

Двоичный ввод/вывод

Форматированный файловый ввод/вывод чисел целесообразно использовать
только при их небольшой величине и малом количестве. В противном случае,
конечно, гораздо эффективнее использовать двоичный ввод/вывод, при котором
числа хранятся таким же образом, как в ОП компьютера, а не в виде символьных
строк. Целочисленные значения занимают 4 байта, тогда как текстовая версия
числа, например «12345», занимает 5 байтов. Значения типа float также всегда
занимают 4 байта. А форматированная версия «6,02314е13» занимает 10 байтов.

В следующем примере показано, как в бинарном виде массив целых чисел запи-
сывается в файл и читается из него. При этом используются две функции — write()
(метод класса ofstream), а также read() (метод ifstream). Эти функции думают о дан-
ных в терминах байтов (тип char). Им все равно, как организованы данные, что они
собой представляют, — они просто переносят байты из буфера в файл и обратно.
Параметрами этих функций являются адрес буфера и его длина. Адрес должен
быть вычислен с использованием reinterpret_cast относительно типа char*. Вторым
параметром является длина в байтах (а не число элементов данных в буфере).

Листинг 12.9. Программа BINIO

// binio.cpp

// Двоичный ввод/вывод целочисленных данных

#include <fstream> // для файловых потоков

#include <iostream>

using namespace std;

const int MAX = 100; // размер буфера

int buff[MAX]; // буфер для целых чисел

 

int main()

{

for(int j=0; j<MAX; j++) // заполнить буфер данными

buff[j] = j; // (0, 1, 2,...)

// создать выходной поток

ofstream os("edata.dat", ios::binary);

// записать в него

os.write(reinterpret_cast<char*>(buff), MAX*sizeof(int));

os.close(); // должен закрыть его

 

for(j=0; j<MAX; j++) // стереть буфер

buff[j] = 0;

// создать входной поток

ifstream is("edata.dat", ios::binary);

// читать из него

is.read(reinterpret_cast<char*>(buff), MAX*sizeof(int));

 

for(j=0; j<MAX; j++) // проверка данных

if(buff[j]!= j)

{ cerr << "Некорректные данные!\n"; return 1; }

cout << "Данные корректны\n";

return 0;

}

При работе с бинарными данными в качестве второго параметра write() и read()
следует использовать ios::binary. Это необходимо по той причине, что текстовый
режим, используемый по умолчанию, допускает несколько вольное обращение
с данными. Например, специальный символ '\n' занимает два байта (на самом
деле это и есть два действия — перевод каретки и перевод строки). Это делает
текст более удобным для чтения в DOS утилитами типа TYPE, но для бинарных
данных такой подход не годится вовсе, так как любой байт, которому не повезло
иметь ASCII-код 10, переводится двумя байтами. Аргумент ios::binary — типичный
пример бита состояния. Мы еще будем говорить об этом при обсуждении функ-
ции ореn() немного позднее в этой главе.

Объектный ввод/вывод

Так как C++ — это все-таки объектно-ориентированный язык, было бы интересно
узнать, как происходит запись объектов в дисковые файлы и чтение из них. Сле-
дующий пример демонстрирует этот процесс. Класс person, использовавшийся ра-
нее в нескольких наших программах (например, в VIRTPERS, глава 11, раздел «Вир-
туальные функции»), создает объекты, с которыми мы сейчас будем работать.

Запись объекта на диск

При записи объекта мы обычно используем бинарный режим. При этом на диск
записывается та же битовая конфигурация, что хранится в памяти. Это придает
уверенности в том, что данные объекта будут обработаны корректно. В приводи-
мой ниже программе OPERS у пользователя запрашивается информация об объек-
те класса person, который потом записывается в файл PERSON.DAT.

Листинг 12.10. Программа OPERS

// opers.cpp

// Сохранение объекта в файле

#include <fstream> // для файловых потоков

#include <iostream>

using namespace std;

///////////////////////////////////////////////////////////

class person // класс person

{

protected:

char name[80]; // имя человека

short age; // возраст

public:

void getData() // получить данные о человеке

{

cout << "Введите имя: "; cin >> name;

cout << "Введите возраст: "; cin >> age;

}

};

///////////////////////////////////////////////////////////

int main()

{

person pers; // создать объект

pers.getData(); // получить данные

// создать объект ofstream

ofstream outfile("PERSON.DAT", ios::binary);

// записать в него

outfile.write(reinterpret_cast<char*>(&pers), sizeof(pers));

return 0;

}

Метод getData() класса person вызывается для того, чтобы запросить у поль-
зователя информацию, которая помещается в объект pers. Вот простой пример
взаимодействия:

Введите имя: Артур
Введите возраст: 60

Содержимое данного объекта записывается на диск с помощью функции write().
Для нахождения длины данных объекта pers используется оператор sizeof.

Чтение объекта с диска

Для чтения пригодится метод read(), что продемонстрировано в следующем лис-
тинге.

Листинг 12.11. Программа IPERS

// ipers.cpp

// Чтение объекта из файла

#include <fstream> // для файловых потоков

#include <iostream>

using namespace std;

///////////////////////////////////////////////////////////

class person // класс person

{

protected:

char name[80]; // Имя человека

short age; // его возраст

public:

void showData() // вывести данные

{

cout << "Имя: " << name << endl;

cout << "Возраст: " << age << endl;

}

};

///////////////////////////////////////////////////////////

int main()

{

person pers; // переменная типа person

ifstream infile("PERSON.DAT", ios::binary);// создать поток

// чтение потока

infile.read(reinterpret_cast<char*>(&pers), sizeof(pers));

pers.showData(); // вывести данные

return 0;

}

 

В результате работы программы будет выведено на экран все то, что было
помещено в файл PERSON.DAT программой OPERS:

Имя: Артур
Возраст: 60


1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 |

Поиск по сайту:



Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Студалл.Орг (0.006 сек.)