Г. Шилтд - Самоучитель C++ (DJVU) (1114955), страница 43
Текст из файла (страница 43)
4. В следующей программе для считывания из файла, созданного в программе примера 3, используется функция геадо: ()ьпс1пс(е <1озСтеат> ()ьпс1пбе <Хзекеап:> из)па пюпезрасе зМ; 1п( та(п () 11зскеат тп("сезс", ьоз;;тп ~ 1оз::Ььпаеу) ) 1.'(! 1п] ( соне « 'майл открыть невозможно'~п" тетптп ); с(опа1е пега; спал зет(ВО); ьп.теас(( (спат ") аьлп, зьаеог (с(оиЫе) ) ~ 1п.геай(вы, 15); зст(14) = '~О сои~ << пьлл << ' ' << ест; ьп.с1озе(); теСптп О; Как и в программе из предыдущего примера, приведение типов внутри функции геадо необходимо, поскольку в С++ указатель одного типа автоматически не преобразуется в указатель другого типа.
<87 Глава 9. Дополнительные возможности ввода/вывода в С++ 5. В следуюшей программе сначала массив доиЫе записывается в файл, а затем считывается обратно. Кроме того, отображается число считанных символов. // Демонстрация работы функции дсоппс () ()1пс1пс(е <4озггеап~> (((пс!цде <~зггеат> ця(пя патпеврасе яТот 1лг п~аьп() ойзСгеав~ опе("Гезт'*, 1оя::опс ] 1оя::Ььпагу) 1т.
(! очаг) ( сопл « "Файл открьггь невовмовво1п"; гегпгп 1; гтовЬ1е тлввз(4] = (1.1, 2.2, З.З, 4.4); опг.игьге( (спаг *) пытв, яьвеог (паля) ) опс. с1ове (); 1гяггеапьп ("сеял", 1оз:: ьп ] 1оя::Ььпагу); 11 (! 1п) ( сопл « "Файл открыть невояможнМп"у гесс и 1; 1п. геас(( (сваг *) апгвпз, я1веог (юввя) ) 3пг 1~ лог (4=04 1<4; 1+-ь) соцГ « пшпя(1] « сонг « '1п') совг « 1п.ссоппг() « " символов считано1п"; 1п.с1ояе (); геспгп О; 1, Измените ответы на упражнения 1 и 3 раздела 9.2 так, чтобы в них использовались функции ае4(), ри4(), геаа() и/или ет44е(3.
(Используйте эти функции там, где они, по вашему мнению, принесут наибольшую отдачу.) Самоучитель Сж+ 2. Дан следующий класс. Напишите программу для вывода содержимого класса в файл. Для этой цели создайте пользовательскую функцию вывода. с1авв ассопп,. [ гпс спзвппж; сиад паже[80); ЙопЬ1е Ьа1апсе; рпЬ11с: ассоппС(тпк с, сЬап *и, ооиЬ1е Ь~ спвсппж =- ср аЬтсру [паже, и); Ьа1апсе = Ь; здесь вужва пользовательская фуякпия вь|вода ) г 9.4. Дополнительная информация о функциях двоичного ввода/вывода Кроме представленной ранее формы, функцию кем() можно перегрузить еше несколькими способами.
Здесь показаны прототипы трех наиболее часто перегружаемых форм: л.яствами Пкет(сваг *бубер, аегеаевл.ге число байя); йвссевж Йкет (сваг "бутвр, втгеагаМже число байт, с)гаг ограяичнтвль) 1пт деФ. (); Первая функция рею() считывает символы в массив, определенный указателем буфер, до тех пор, пока либо не считано столько символов, сколько задано параметром число бийт — 1. либо не встретился символ конца файла.
В конце массива, заданного указателем буфер, функция ре10 помешает ноль. Если в потоке ввода встретится символ новой строки, он не извлекается, а остается в потоке до следующей операции ввода. Вторая функция йе)() считывает символы в массив, определенный указателем буфер, до тех пор, пока либо не считано столько символов, сколько задано параметром число байт — 1, либо не встретился символ, заданный параметром ограпичитель.
либо не встретился символ конца файла. В конце массива, заданного указателем буфер, функция рею() помешает ноль. Если в потоке ввода встретится символ ограиичитель, он не извлекается, а остается в потоке до следующей операции ввода. Третья функция ке10 возвращает из потока следуюший символ. Она возвращает символ ЕОГ, если достигнут конец файла. Эта форма функции йе$О напоминает функцию ре1с() языка С. 289 Глава 9. Дополнительные возможности ввода/вывода в С+<- Другой функцией для реализации ввода является функция Иейпео. Эта функция — член всех потоковых классов ввода.
Ниже показаны ее прототипы: з.вссевгв Пвс1ипе(сваг *буфер, вЕсеатвкве число байи); 1.вЕхева ь((еЕЫпе (сиав *буфер, всгеввввве число байт, сиаг ограиичивелв) Первая функция считывает символы в массив, обозначенный указателем буфер, до тех пор, пока либо не считано столько символов, сколько задано параметром число 6айт — 1, либо не встретился символ новой строки, либо не встретился символ конца файла.
В конце массива, заданного указателем буфер, функция пе1йпеО помещает ноль. Если в потоке ввода встретится символ новой строки, он извлекается, но не помещается в массив. Вторая функция считывает символы в массив, обозначенный указателем буфер, до тех пор, пока либо не считано столько символов, сколько задано параметром число 6айт — 1, либо не встретился символ ограничитель, либо не встретился символ конца файла. В конце массива, заданного указателем буфер, функция пе11!пео помещает ноль.
Если в потоке ввода встретится символ ограничитель, он извлекается, но не помещается в массив. Как можно заметить, обе версии функции пе111пеЦ фактически тождественны версиям пе1(буфер, число байт) и пе1(буфер,число 6айт, ограничитель) функции пе10. Обе считывают символы из потока ввода и помещают их в массив, обозначенный указателем буфер до тех пор, пока либо нс считано число 6айт — 1 символов, либо не встретился символ ограничитель или символ конца файла. Отличие между функциями пе10 и пей(пе() в том, что функция пе111пео считывает и удаляет из потока ввода символ ограничитель, а функция пе10 — пет.
Используя функцию рееЦ), можно получить следующий символ из потока ввода без его удаления из потока. Функция является членом потоковых классов ввода и имеет следующий прототип: )пг рее)г () ) Функция возвращает следующий символ из потока или, если достигнут конец файла, символ ЕОЕ С помощью функции рп(ппсЕО, являющейся членом потоковых классов ввода, можно возвратить последний считанный из потока символ обратно в поток. Ниже показан прототип этой функции: з.вЕвевгв ЛрШЬас1с (сЬаг О); Здесь с — это последний считанный из потока символ. При выполнении вывода данные не сразу записываются на связанное с потоком физическое устройство, а информация временно сохраняется во внутреннем буфере. Только после заполнения буфера его содержимое переписывается на диск.
Однако вызов функции Лы)(() вызывает физическую Самоучитель С++ запись информации на диск до заполнения буфера. Ниже показан прототип функции ПввЬ0, являющейся членом потоковых классов вывода: оевшеав 6ПпвЬО Вызовы функции йцзЬ0 оправданы при работе в неблагоприятной обста- новке (например, в ситуациях, когда часто случаются сбои по питанию). 1. Как вы знаете, при использовании для считывания строки оператора >>, считывание прекращается при встрече первого разделительного символа. При наличии в строке пробелов такое считывание становится невозможным.
Однако, как показано в программе, с помощью функции Кейпео можно решить эту проблему: // Использование функции сев11пе() для считывания строки с пробелами 1)ьпс1иг)е <1оввгеаш> В)пс)цде <Гаегеаш> цв) пя пагпеврасе вМ; )п1 таьп1) с)заг асг (Во); соц1 « "Введите ваше имя: сьп.дес11пе1в1г, 79): сонг « вгг « '1п' гегигп О; В данном случае ограничителем для функции яе1йпе0 является символ новой строки.
Это делает выполнение функции рейвео очень похожей на выполнение стандартной функции Кетво. 2. В реальном программировании особенно полезны функции рееК() и ри~ЬасЩ Они позволяют упростить управление, когда неизвестен тип вводимой в каждый конкретный момент времени информации. Следующая программа иллюстрирует зто. В ней из файла считываются строки либо целые. Строки и целые могут следовать в любом порядке. // Демонстрация работы функции реек1) )) апс1цг)е <тоасгеат> Н)пс!цде <гвсгеазв> Мтпс1цс)е <сощуре> ив)пя пагпсврасе вМ; 1п1 гпа)п () 291 Глава 9. Дополнительные воэможности ввода/вывода в С++ сЬаг сЬ; оХзГгеав оцг ("Севе", 1ов:: осг ' ьов:: Ььпагу) т уг((оцг) ( сопя « "Файл открыть невозможно~в"," гесцгп 1; сЬаг зсг(60), *рг опс « '23 « "сЬ1я 1я а сеял" « 23; оцс « "Не11о сЬеге!" « 99 « "вдГ" « епй1; оцс.
с1ове (); 1Гзггеат 1п("сев~", 5оз:;1п ~ 1оя::Ь1пагу); 1~(!1п) ( соцг « "Файл открыть невозможноМ"' гегцгп 1; йо ( р .=- ясг; сЬ = 1п.рее)г()г // выяснение типа следующего символа Н (1зе(191г(сЬ)) ( нЬ11е(1зг(191~(*р=1п.де1()),) ре+; ll считывание целого 1п.рцсЬаск(+р); l/ возврат символа в поток *р = '~О'; // заканчиваем строку нулем соцс « "целое: " « адо1(зт.г)г е1яе 1~(1за1рьа[сь)) ( /т считьвание строки иЬ11е(1за1рЬа(*р=ьп.дед())) р++; 1п.рцсЬасХ(*р)т // возврат символа в поток *р — '~0'у т/ заканчиваем строку нулем сопя « "Строка: " « ясг; ) е1яе 1п.9ес(); // прогО~ск сонг « '~п'; ) ыЬ11е(!1п.еой()); 1п,с1озе()) гесцгп О; 1.
Перепишите программу из примера 1 так, чтобы вместо функции $ЕЖйЕО использовать функцию 9е10. Будет ли отличаться работа программы? Самоучитель С+~- 2. Напишите программу для построчного считывания текстового файла и вывода каждой считанной строки на экран. Используйте функцию Вейве(). 3. Подумайте о ситуациях, в которых может оказаться полезным вызов функции 1)ийО.