Смекни!
smekni.com

Основы алгоритмического языка С++ (стр. 21 из 21)

// C++ демонстрация файлового ввода/вывода прямого доступа

Программа листинга 10.3 объявляет класс VmArray. Этот класс моделируетдинамический базирующийся на диске массив, который сохраняет все егоэлементы в двоичном файле прямого доступа. Заметьте, что в этом классеобъявлен экземпляр класса fstream и что не существует указателя на динамический массив. Класс объявляет конструктор, деструктор и ряд функций-компонентов.

Конструктор класса имеет два параметра: Size и filename. Параметр Size задаетразмер виртуального массива. Параметр filename именует двоичный файл,который сохраняет элементы экземпляров класса. Конструктор открывает поток f,используя потоковую функцию open и передавая ей в качестве аргументовfilename и выражение для режима работы с файлом ios::in | ios::out | ios::binary.

Это выражение указывает, что поток открывается для двоичного ввода/вывода (тоесть режима прямого доступа). Если конструктор успешно открывает файловыйпоток, он заполняет файл пустыми строками. Деструктор класса выполняетпростую задачу закрытия файлового потока f.

Функции setElem и getElem поддерживают прямой доступ к элементаммассива. Эти функции используют потоковую функцию seekg, чтобыустанавливать указатель потока на соответствующий элемент массива. Затемфункция setElem вызывает потоковую функцию write для сохранения элементамассива (передаваемый параметром str). Напротив, функция getElem называетпотоковую функцию read, чтобы получить элемент массива (возвращаемый черезаргумент str). Обе функции возвращают результат типа bad, который указываетна успешность операции ввода/вывода.

Класс VmArray также объявляет функцию BubbleSort для сортировкиэлементов виртуального массива. Эта функция использует функции-элементыgetElem и setElem для доступа и свопинга элементов массива. Затем, наконец,запускается последняя функция-элемент display для элементов виртуальногомассива, которая посылает их на экран. Функция main выполняет следующие задачи:

Объявляет экземпляр arr класса VmArray. (Этот экземпляр сохраняет 10 строкв двоичном файле ARR.DAT)

Присваивает случайное значение элементам экземпляра аот, используя циклfor (строки 97 и 98).

Отображает несортированные элементы экземпляра arr, вызывая функцию-элемент display.

Сортирует массив, вызывая функцию BubbleSort.

Отображает сортированные элементы экземпляра arr.

Заключение

Сегодняшний урок представил краткое введение в библиотеку ввода/выводаC++ и вынес на обсуждение следующие вопросы:

Общие функции ввода/вывода, включая open, close, good, fail и оператор !.

Функция open открывает файловый поток ввода/вывода и поддерживаетпопеременный и множественный режимы ввода/вывода. Функция closeзакрывает файловый поток. Функции good и fail индицируют успешную илиошибочную, соответственно, потоковую операцию ввода/вывода.

C++ позволяет выполнять последовательный потоковый ввод/вывод длятекста с использованием операций < и >, так же как и при помощи потоковойфункции getline. Операция < позволяет записать символы и строки (а также идругие предопределенные типы данных). Операция > применяется для получения символов. Функция getline позволяет вашему приложениюсчитывать строки с клавиатуры или из текстового файла.

Последовательный потоковый ввод/вывод двоичных данных используетпотоковые функции write или read для записи или считывания данных изпеременных любого типа.

Потоковый ввод/вывод прямого доступа для двоичных данных используетфункцию seekg в объединении с функциями read и write. Функция seekgпозволяет вам передвигать потоковый указатель либо в абсолютное, либо вотносительное положение в потоке.

Вопросы и ответы

Как можно эмулировать прямой доступ к строкам в текстовом файле?

Сначала считывайте строки из файла как текст, получайте длину строк (плюсдва символа для конца каждой строки) и сохраняйте накапливаемую длину вспециальном массиве. (Назовите его, например, lineIndex) Этот массивсохраняет позицию байта, где начинается каждая строка. Последний элементмассива будет содержать размер файла. Для доступа к строке номер i,используйте функцию seek или seekg, чтобы найти смещение для lineIndex[i].Размер строки номер i равен lineIndex[i+1] - lineIndex[i+1].

Как написать процедуру общего назначения для копирования между входным ивыходным файловым потоком?

Вам необходимо использовать потоковую функцию gcount() для полученияряда байт фактически читаемых в последнем неформатированном потоковомвводе. Вот функция copyStream:

void copyStream(fstreamit fin, fstreamil fout,

unsigned char* buffer, int buffSize)

{

int n;

while (fin. read (buffer, buffaize))

{

n = fin.gcount();

fout.write (buffer, n);

}

}

Практикум

Контрольные вопросы

1. Верно или нет? Потоковые функции ввода/вывода read и write способныправильно считывать и записывать данные любого типа.

2. Верно или нет? Потоковые функции ввода/вывода read и write способныправильно считывать и записывать данные любого типа, не имеющихуказателей.

3. Верно или нет? Функции seek и seekg расширяют файл, когда вы передаетеиндекс, который на один или более байт превышает текущий конец файла.

4. Верно или нет? Аргументы функций seek и seekg не требуют проверкидиапазона.

Упражнение

Создайте программу VSEARCH.CPP, модифицируя программуVIRTUAL.CPP. Класс VmArray в VSEARCH.CPP должен иметь функциюbinSearch, которая проводит двоичный поиск в элементах сортированного массива. Добавьте цикл в конец функции main для поиска в массиве arr, используянеупорядоченные данные инициализирующего списка. (Элементы этого спискадоступны при использовании данных-указателей.)