Г. Шилтд - Самоучитель C++ (DJVU) (1114955), страница 41
Текст из файла (страница 41)
гесигп 0; Как можно заметить, созданный вами манипулятор аегнр используется в качестве части выражения ввода/вывода точно так же, как это делается с любым встраиваемым манипулятором. 2. Пользовательские манипуляторы не обязательно должны быть сложными. Например, простые манипуляторы а1п() и йо$е9 обеспечивают простой и удобный способ вывода часто встречающихся слов и фраз. ()хпс1пе(е <1овегеав> па1по пагпеврасе в~Ф l/ Внимание: ояегеага аасп (оясгеа~п ге~геев) ( я Сгеап~ << "Внимаьзае: геснгп я' геапн !! Пожалуйста, не забудьте: оясгеага алеее (оясгеип «в~гевп~) ( ясгеега « "Пожалуйста, не забудьте: геспгп ясгеало упсвихп ( ) ( соне « асп « "Высокое напряжение~и"; сонь « поТе « "Выклю лать светХп"; гесигп 0; Несмотря на простоту, такие манипуляторы оградят вас от необходимости частого набора одних и тех же слов и фраз.
Глава 9. Дополнительные возможности ввода/вывода в С++ 2?5 3. В следующей программе создается манипулятор це(раяо, который вызывает гудок динамика и затем предлагает ввести пароль: () ьпс1пс(е .<1 о в Стева» ()1пс1иг)е <свтг1пя> иь1пя пагпеврасе згбг // Простой манипулятор ввода ьвт,геип Ьдатравв (ьвСгеат авт.ген) сощ « '',а'; // гудок динамика соиС « "Введите пароль: гегпгп вггеагп; ьпе паз.п() с*наг ри(ВО); до ( с(п » аегравв » рж; ) оп!е (втгсгпр(ри „"пароль" ) ); сонг « "Пароль введен верно~в"; ге(иго 0; 1.
Создайте манипулятор вывода для отображения текущего системного време- ни и даты. Назовите манипулятор Ыо. 2. Создайте манипулятор вывода вейехО, который осуществляет вывод в шестнадцатеричной системе счисления и устанавливает флаги иррегсаве и в))оъЬаае.
Кроме того, создайте манипулятор вывода гевеьО, который отменяет изменения, сделанные манипулятором вег)гехах. 3. Создайте манипулятор ввода аИрсааго, который поочередно то считывает, то пропускает каждые десять символов потока ввода. 9.2. Основы Файлового ввода/вывода Как было отмечено в предыдущей главе, файловый и консольный ввод/вывод очень близко связаны.
Фактически файловый ввод/вывод поддерживается той же иерархией классов, что и консольный ввод/вывод. 276 Самоучитель Сч-ь Таким образом, все, что вы уже узнали о вводе/выводе, вполне применимо и к файлам. Естественно, что обработка файлов предполагает и кое-что новое. Для реализации файлового ввода/вывода, необходимо включить в программу заголовок <Ыгеаа>. В нем определено несколько классов, включая классы !Ыгеаа, оЫгеаш и Ыгеаа. Эти классы являются производными от классов Ыгеаа и ок1тевш Вспомните, что классы Ыгеав и оя1геаа, в свою очередь, являются производными от класса юя, поэтому классы ггЫгеагв, оЫгеаа и Ьйеип также имеют доступ ко всем операциям, определяемым классом юя (это обсуждалось в предыдущей главе).
В С++ файл открывается посредством его связывания с потоком. Имеется три типа потоков: ввода, вывода и ввода/вывода. Перед тем как открыть файл, нужно, во-первых, создать поток. Для создания потока ввода необходимо объявить объект типа )Ыгеаа. Для создания потока вывода — объект типа оЫгеагп. Потоки, которые реализуют одновременно ввод и вывод, должны объявляться как объекты типа Ыгеав. Например, в следующем фрагменте создается один поток для ввода, один поток для вывода и еще один поток одновременно для ввода и для вывода: Ггявгеатп Ьп; уу ввод отясгеат оыв; уу вывод гя геатп то; уу ввод и вывод После создания потока, одним из способов связать его с файлом является функция орепо.
Эта функция является членом каждого из трех потоковых классов. Здесь показаны ее прототипы для каждого класса: моЫ Ывйгевт: перев(сопв1 сваг *вмв файла, орептасГе режим = ~ов:: ~л) чоЫ огвФгеат::ореп(соввФ. сваг *жив файла, оретппос1е режим = аов::онп 1 аов:: Фгнпс) чоЫ Кв1гевт: перев(свпвп сваг *имв Файла, Ореппос1е режим = гоя:: тп ~ хов:: оыс) Здесь «мя 4айла- имя файла, в которое может входить и спецификатор пути. Значениеревсим задает режим открытия файла.
Оно должно быть значением типа орепвюйе, которое является перечислением, определенным в классе юв. Значениережим может быть одним из следующих: гов::арр тоя::асе 1оя: шпагу тоя:: 1.п тоя::оно 1.оя::ггипс Вы можете объединить два или более этих значения с помощью оператора ОК. Рассмотрим, что означает каждое из этих значений. 277 Глава 9. Дополнительные возможности ввода/вывода в С++ Значение )оз::арр вызывает открытие файла в режиме добавления в конец файла.' Это значение может применяться только к файлам, открываемым для вывода. Значение кьпа1е задает режим поиска конца файла при его открытии.
Хотя значение ювпаге вызывает поиск конца файла, тем не менее, операции ввода/вывода могут быть выполнены в любом месте файла. Значение юяпш задает режим открытия файла для ввода. Значение 1овпоМ задает режим открытия файла для вывода. Значение ювпЫпягу вызывает открытие файла в двоичном режиме. По умолчанию все файлы открываются в текстовом режиме. В текстовом режиме имеет место преобразование некоторых символов, например, последовательность символов "возврат каретки/перевод строки" превращается в символ новой строки. Если же файл открывается в двоичном режиме, такого преобразования не выполняется. Запомните, что любой файл, независимо от того, что в нем содержится — отформатированный текст или необработанные данные — может быть открыт как в текстовом, так и в двоичном режиме. Отличие между ними только в отсутствии или наличии упомянутого символьного преобразования. Значение юзпФгипс приводит к удалению содержимого ранее существовавшего файла с тем же названием и усечению его до нулевой длины.
При создании потока вывода с помощью ключевого слова вЫгеат любой ранее существовавший файл с тем же именем автоматически усекается до нулевой длины. В следующем фрагменте для вывода открывается файл ген: о1вбтеата лув~шеаа; п~увотеап~.ореп("кеа. "); В этом примере параметррежим функции ореиО по умолчанию устанавливается в значение, соответствующее типу открываемого потока, поэтому нет необходимости указывать его явно.
Если выполнение функции орепО завершилось с ошибкой, в булевом выражении поток будет равен значению Ыве. Этот факт можно использовать для проверки правильности открытия файла с помощью, например, такой инструкции: Ь1 (! п~увт теап~) сорб << ьФайя открыть иевоаможио~п"; програмиа обработки ошибки открытия файла Как правило, перед тем как пытаться получить доступ к файлу, следует проверить результат выполнения функции орепо.
Проверить правильность открытия файла можно также с помощью функции )в орепо, являющейся членом классов ИвГгеап), оЫгеып и Ыгеап). Ниже показан прототип этой функции: )аоо1 (в ореп() 278 Самоучитель СС+ Функция возвращает истину, если поток удалось связать с открытым файлом, в противном случае функция возвращает ложь. Например, в следующем фрагменте проверяется, открыт ли файл, связанный с потоком п)уьггеа)п: 1й(.'шувегеаж.з.е орет () ) г сонг << "Файл не открьгг~н"; // Хотя использовать функцию орепО для открытия файла в целом правильно, часто вы этого делать не будете, поскольку у классов 1Ыгеатя, оЫгеат и ЬГгеяя есть конструкторы, которые открывают файл автоматически.
Конструкторы имеют те же параметры, в том числе и задаваемые по умолчанию. что и функция орели. Поэтому чаще вы будете пользоваться таким способом открытия файла: )Гвггеагв гвуаггеагв ~ "гвуг1ге") г // открытие файла для ввода Как уже установлено, если по каким-то причинам файл не открывается, переменная, соответствующая потоку, в условной инструкции будет равна значению ГаЬе. Поэтому, независимо от того, используете ли вы конструктор или явно вызываете функцию орепО, вам потребуется убедиться в успешном открытии файла путем проверки значения потока. Для закрытия файла используйте функцию-член с1озеО. Например, чтобы закрыть файл, связанный с потоком туз1геаш, необходима следующая инструкция: гауаггеага.с1оае1); Функция с1ояе() не имеет параметров и возвращаемого значения.
С помощью функции еоГО, являющейся членом класса 1оз, можно определить, был ли достигнут конец файла ввода. Ниже показан прототип этой функции: ЬооГ еог(); Функция возвращает истину, если был достигнут конец файла; в противном случае функция возвращает ложь. После того как файл открыт, очень легко считать из него или записать в него текстовые данные. Просто используйте операторы <( и » так же, как это делалось для консольного ввода/вывода, только замените поток сгп или соШ тем потоком, который связан с файлом.
Так же, как и операторы (< и » для чтения из файла и записи в файл годятся функции С вЂ” ГрппГГО и ЬсапГО. Вся информация в файле хранится в том же формате, как если бы она находилась на экране. Следовательно, файл, созданный с помощью оператора «, представляет из себя файл с отформатированным текстом, и Глава 9. Дополнительные возможности ввода/вывода в С++ наоборот, любой файл, содержимое которого считывается с помошью оператора », должен быть файлом с отформатированным текстом. То есть, как правило, файлы с отформатированным текстом, которые вы будете обрабатывать, используя операторы « и », следует открывать в текстовом, а не в двоичном режиме.