Создание собственных манипуляторных функций



 

Программист может создавать собственные манипуляторные функции. Существует два типа манипуляторных функций: принимающие и не принимающие аргументы. Для создания параметризованных манипуляторов используются методы, рассмотрение которых выходит за рамки этой книги. Однако создание манипуляторов, которые не имеют параметров, не вызывает особых трудностей.

Все манипуляторные функции вывода данных без параметров имеют следующую структуру.

 

 

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

В следующей программе создается манипулятор setup() , который устанавливает флаг выравнивания по левому краю, ширину поля равной 10 и задает в качестве заполняющего символа знак доллара.

 

 

Собственные манипуляторы полезны по двум причинам. Во‑первых, иногда возникает необходимость выполнять операции ввода‑вывода с использованием устройства, к которому ни один из встроенных манипуляторов не применяется (например, плоттер). В этом случае создание собственных манипуляторов сделает вывод данных на это устройство более удобным. Во‑вторых, может оказаться, что у вас в программе некоторая последовательность инструкций повторяется несколько раз. И тогда вы можете объединить эти операции в один манипулятор, как показано в предыдущей программе.

Все манипуляторные функции ввода данных без параметров имеют следующую структуру.

 

 

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

 

 

Помните: очень важно, чтобы ваш манипулятор возвращал потоковый объект (элемент stream ). В противном случае этот манипулятор нельзя будет использовать в составном выражении ввода или вывода.

 

Файловый ввод‑вывод

 

В С++‑системе ввода‑вывода также предусмотрены средства для выполнения соответствующих операций с использованием файлов. Файловые операции ввода‑вывода можно реализовать после включения в программу заголовка <fstream> , в котором определены все необходимые для этого классы и значения.

 

Как открыть и закрыть файл

 

В C++ файл открывается путем связывания его с потоком. Как вы знаете, существуют потоки трех типов: ввода , вывода и ввода‑вывода . Чтобы открыть входной поток, необходимо объявить потоковый объект типа ifstream . Для открытия выходного потока нужно объявить поток класса ofstream . Поток, который предполагается использовать для операций как ввода, так и вывода, должен быть объявлен как объект класса fstream . Например, при выполнении следующего фрагмента кода будет создан входной поток, выходной и поток, позволяющий выполнение операций в обоих направлениях.

 

 

Чтобы открыть файл, используйте функцию open().

Создав поток, его нужно связать с файлом. Это можно сделать с помощью функции open() , причем в каждом из трех потоковых классов есть своя функция‑член open() . Представим их прототипы.

 

 

Здесь элемент filename означает имя файла, которое может включать спецификатор пути. Элемент mode определяет способ открытия файла. Он должен принимать одно или несколько значений перечисления openmode , которое определено в классе ios .

 

 

Несколько значений перечисления openmode можно объединять посредством логического сложения (ИЛИ ).

На заметку. Параметр mode для функции fstream::open() может не устанавливаться по умолчанию равным значению in | out (это зависит от используемого компилятора). Поэтому при необходимости этот параметр вам придется задавать в явном виде.

Включение значения ios::арр в параметр mode обеспечит присоединение к концу файла всех выводимых данных. Это значение можно применять только к файлам, открытым для вывода данных. При открытии файла с использованием значения ios::ate поиск будет начинаться с конца файла. Несмотря на это, операции ввода‑вывода могут по‑прежнему выполняться по всему файлу.

Значение ios::in говорит о том, что данный файл открывается для ввода данных, а значение ios::out обеспечивает открытие файла для вывода данных.

Значение ios::binary позволяет открыть файл в двоичном режиме. По умолчанию все файлы открываются в текстовом режиме. Как упоминалось выше, в текстовом режиме могут происходить некоторые преобразования символов (например, последовательность, состоящая из символов возврата каретки и перехода на новую строку, может быть преобразована в символ новой строки). При открытии файла в двоичном режиме никакого преобразования символов не выполняется. Следует иметь в виду, любой файл, содержащий форматированный текст или еще необработанные данные, можно открыть как в двоичном, так и в текстовом режиме. Единственное различие между этими режимами состоит в преобразовании (или нет) символов.

Использование значения ios::trunc приводит к разрушению содержимого файла, имя которого совпадает с параметром filename , а сам этот файл усекается до нулевой длины. При создании выходного потока типа ofstream любой существующий файл с именем filename автоматически усекается до нулевой длины.

При выполнении следующего фрагмента кода открывается обычный выходной файл.

 

 

Поскольку параметр mode функции open() по умолчанию устанавливается равным значению, соответствующему типу открываемого потока, в предыдущем примере вообще нет необходимости задавать его значение.

Не открытый в результате неудачного выполнения функции open() поток при использовании в булевом выражении устанавливается равным значению ЛОЖЬ. Этот факт может служить для подтверждения успешного открытия файла, например, с помощью такой if‑инструкции.

 

 

Прежде чем делать попытку получения доступа к файлу, следует всегда проверять результат вызова функции open() .

Можно также проверить факт успешного открытия файла с помощью функции is_open() , которая является членом классов fstream , ifstream и ofstream . Вот ее прототип,

 

 

Эта функция возвращает значение ИСТИНА, если поток связан с открытым файлом, и ЛОЖЬ – в противном случае. Например, используя следующий код, можно узнать, открыт ли в данный момент потоковый объект mystream .

 

 

Хотя вполне корректно использовать функцию open() для открытия файла, в большинстве случаев это делается по‑другому, поскольку классы ifstream , ofstream и fstream включают конструкторы, которые автоматически открывают заданный файл. Параметры у этих конструкторов и их значения (действующие по умолчанию) совпадают с параметрами и соответствующими значениями функции open() . Поэтому чаще всего файл открывается так, как показано в следующем примере,

 

 

Если по какой‑то причине файл открыть невозможно, потоковая переменная, связываемая с этим файлом, устанавливается равной значению ЛОЖЬ.

Чтобы закрыть файл, вызовите функцию close().

Чтобы закрыть файл, используйте функцию‑член close() . Например, чтобы закрыть файл, связанный с потоковым объектом mystream , используйте такую инструкцию,

 

 

Функция close() не имеет параметров и не возвращает никакого значения.

 


Дата добавления: 2018-09-22; просмотров: 372; Мы поможем в написании вашей работы!

Поделиться с друзьями:






Мы поможем в написании ваших работ!