- •11. Инкапсуляция
- •12. Полиморфизм
- •13. Наследование
- •Управление доступом
- •Элементы класса
- •Элементы данных
- •Элементы функции
- •15. Перегрузка функций
- •16. Конструкторы и деструкторы Конструктор
- •Деструктор
- •17. Параметризированные конструкторы
- •18. Дружественные функции
- •19. Inline-функции
- •20. Передача объектов в функции
- •21. Возвращение объектов функциями
- •22. Массивы объектов
- •23. Указатели на объекты
- •24. Указатель this
- •25. Перегрузка операторов
- •26. Ссылки
- •27. Наследование и спецификаторы доступа
- •28. Конструкторы и деструкторы производных классов
- •29. Множественное наследование. Передача параметров в конструктор базового класса
- •30. Указатели и ссылки на производные типы
- •31. Виртуальные функции
- •32. Чисто виртуальные функции и абстрактные типы
- •33. Раннее и позднее связывание
- •35. Создание собственных операторов вставки и извлечения.
- •36. Форматирование ввода-вывода
- •37. Файловый ввод-вывод
- •38. Чтение и запись в текстовые файлы
- •39. Двоичные файлы
- •40. Функции-шаблоны
- •41. Классы-шаблоны
- •42. Использование пространства имён
- •43. Контейнерные классы
- •46. Основы обработки исключений
- •47. Идентификация типа во время исполнения (rtti)
- •49. Виртуальный базовый класс
39. Двоичные файлы
Имеется несколько способов для записи двоичных данных в файл и чтения из файла. В первую очередь, можно записать байт с помощью функции-члена put() и прочитать байт, используя функцию-член get(). Функция get() имеет много форм, но наиболее употребительна показанная ниже версия, где приведена также функция put():
istream &get(char &ch);
ostream &put(char ch);
Функция get() читает единственный символ из ассоциированного потока и помещает его значение в ch. Она возвращает ссылку на поток. Функция put() пишет ch в поток и возвращает ссылку на этот поток.
Следующая программа выводит содержимое любого файла на экран.
Пример
#include <iostream>
#include <fstream>
using namespace std;
int main(int argc, char *argv[])
{
char ch;
if (argc!=2) {
cout << "Bad command line!";
return 1;
}
ifstream in(argv[1], ios::in | ios::binary);
if (!in) {
cout << "Cannot open file.\n";
return 1;
}
while (in) {
in.get(ch);
cout << ch;
}
system("pause");
in.close();
return 1;
}
Следующая программа использует функция put() для записи строки, содержащей не ASCII-символы.
Пример
#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 *buf, int num);
Функция read() читает num байт из ассоциированного потока и посылает их в буфер buf. Функция write() пишет num байт в ассоциированный поток из буфера buf.
Следующая программа пишет и потом читает массив целых чисел:
Пример
#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();
Она возвращает число символов, прочитанных последним оператором двоичного ввода.