Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Вот еще 2.5.8.11.14.17.20.23.26.29.32..docx
Скачиваний:
2
Добавлен:
25.09.2019
Размер:
30.36 Кб
Скачать

17.Бинарные и типизированные фаилы.Общие черты и отличия.Представления данных в них.

Текстовые и двоичные файлы(типизированные и бинарные)

Текстовые файлы, с которыми мы имели дело до сих пор, отличаются двумя свойствами:

1.файлы делятся на строки, и конец строки отмечается специальным символом «new line» (новая строка), роль которого в системе ввода/вывода С++ играет ‘\n’;

2.при вводе чисел выполняется преобразование из символьного вида во внутренний формат (вспомните функцию atoi — см. листинг 3.12); при выводе чисел — из внутреннего формата в символьный;

Двоичные файлы, как вы понимаете, этими свойствами не обладают. Это означает, что двоичные файлы на строки не делятся, и при вводе/выводе никаких преобразований не делается. При операции записи в двоичный файл попадает ровно столько байтов, сколько записываемый объект занимает в памяти. Например, целое число, записанное в двоичный файл, займет на диске sizeof(int) байтов. Это существенно отличается от записи в текстовый файл, где количество записываемых по умолчанию символов зависит от величины числа. Например, число 1 в текстовом файле займет 1 байт, а 55555 — 5 байтов. Примерами двоичных файлов могут служить файлы выполняемых программ (с расширением exe). Чтобы прочувствовать разницу, давайте напишем программу, которая генерируют 1000 целых случайных чисел и выводит их в файлы. Один файл будет текстовым, а другой — двоичным.

Тут нас поджидает одна проблема: в классах fstream, ifstream, ofstream отсутствуют методы ввода/вывода целых чисел в файл. Однако нам нет необходимости писать собственные функции, если мы умеем работать с указателями. Первый параметр методов read/write — это char *. Поэтому мы можем непосредственно обращаться к этим методам, используя подходящее преобразование указателей. Посмотрите, как это делается для типа long; from — входной поток, to — выходной поток (листинг 6.15).

//Листинг 6.15. Ввод/вывод встроенных типов данных

long a;

from.read((char *)&a, sizeof(long));

to.write((char *)&a, sizeof(long));

Преобразование типов можно делать и в стиле С++:

to.write(reinterpret_cast<char *>(&a), sizeof(long));

from.read(reinterpret_cast<char *>(&a), sizeof(long));

20.Пользовательские типы данных.Структуры.Массивы структур/записей.

К пользовательским типам данных относятся нестандартные данные, о структуре которых система не имеет представления, и операции над которыми стандартом языка C не определены. Структура таких данных становится известной компилятору только по описанию, содержащемуся в тексте исходной программы. К пользовательским данным такого типа относятся массивы (о них речь шла в предыдущем разделе), структуры (в других алгоритмических языках они известны под термином записи ), перечисления (в некоторых книгах по языкам C, C++ их относят к целочисленным данным) и объединения.

9.1. Структуры

Первоначальным образом для данных типа структур явились строки таблиц, с которыми знаком любой человек. Характерным для таблиц любого содержания является наличие столбцов, в каждом из которых хранятся однотипные данные. Однако в соседних столбцах типы данных могут отличаться. Если специфической особенностью массивов является использование одного и того же типа для всех элементов массива, то строки таблиц можно представлять как последовательность полей данных разного типа. Для каждого поля строки таблицы известно наименование соответствующего столбца таблицы и тип размещаемого в этом поле значения. Например, поле "Фамилия" заполняется текстовой информацией, поле "Год рождения" хранит целочисленные данные, на поле "Пол" достаточно записывать единственный символ 'М' или 'Ж' и т.д.

9.1.1. Объявление и инициализация структур

То, что принято называть "шапкой" таблицы в языках программирования носит название шаблона структуры. Например, шаблон структуры, описывающей данные о книге, может быть устроен следующим образом:

struct book {

char title[40]; //наименование

char authors[30]; //авторы

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

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

int pages; //количество страниц

float price; //цена }

Для доступа к соответствующим полям структур используются составные имена, образованные из имени структуры и имени поля:

strcpy(b1.title,"C++:Экспресс курс");

strcpy(b1.authors,"В.Лаптев");

cout << b1.title;

b1.year=2004;

Если мы имеем дело с указателем, который настроен на адрес структуры, то составные имена записываются с использованием двух символов "->":

struct book *p=&b1; //указатель на структуру

strcpy(p->title,"C++:Экспресс курс"

strcpy(p->authors,"В.Лаптев");

cout << p->title;

p->year=2004;

Структуры могут объединяться в массивы:

struct book c[20]; //массив структур

И тогда для доступа к полям соответствующего элемента используются индексированные составные имена:

strcpy(с[2].title,"Язык C++ "

strcpy(c[2].authors,"В.В.Подбельский");

cout << c[2].title;

c[2].year=1996;

struct book *pс=с;

strcpy(pс[2]->title,"C++:Экспресс курс"

strcpy(pс[2]->authors,"В.Лаптев");

cout << pс[2]->title;

pс[2]->year=2004;