Г. Шилдт - Полный справочник по C++ (1109478), страница 82
Текст из файла (страница 82)
В нем определены некоторые классы, в частности, 1свеявав, освехват и Свеявазв Эти классы являются производными от классов 1веяввв, овеяват и 1овеяввя> соответственно. Слслуег помнить, что классы 1вехввзв, овекеа>а и 1овехевзв, в свою очередь, являются производными от класса хов, рассмотренного в предыдущей главе. Файловая система использует также класс с11в?>пе, прелое>авляюший низкО- уровневые средства управления файловым потоком. Обычно класс с11в?звв непосредственно не применяется„однако он является составной частью других классов. Открытие и закрытие файла В языке С++ открытие Файла означает его связывание с потоком. Следовательно, сначала необходимо получить поток.
Сушествуют три вида потоков: ввода, вывода и ввода-вывода. Для того чтобь> создать поток ввода, необходилю объявить поток, представляюший собой объект класса 1хввхва>в Для генерации потока вывода необходимо объявить поток, представляюший собой объект класса освехвв>в Потоки, осушествляюшие ввод и вывод, объявляются как объекты класса свеквввь Например, в следуюшем фрагменте создается поток ввода, поток вывода и поток авода-вывода. | 1гвегеаа> зп; >/ Ввод ойяггеал> осе> // Вывод ?ясяеаа> 1о; У/ Ввод и вывод Создан»ый поток можно связать с файлом с помощью функции орвп().
Эта функция являешься членом каждого из трех потоковых классов. Ее прототипы в каждом классе показаны ниже. 1?яегеаи>з >преп(сопев с?>ах "(>(еиате, 1оя::преп>аое?е >аиде = 1ояз >1п» 11я> ееа>и". >ореп(сопят с»ах ?>(еиате, 1оя::среда>ое?е тоде = зов>:опе ! 1ояззсзппс(> 1?я> ееаа>з>преп[сопят с?>ах +й(еиате, 1овз>орегеаое?е тоде = 1оя» 1п ! зая::оце(з Здесь параметр?>(елате задает имя Файла. Он может содержать путь к этому Файлу. Значение параметра тоде определяет способ открызия файла. Этот параметр может принимать следующие значения, описанные в функции орввто>тв.
1оя::арр 1аяззаее 1ая:>Ыпаху з.ая::1п з.ов»оие 1оя>збгипс Данные значения можно комбинировать с помошью логической операции "ИЛИ". Часть й. Язык С++ Чтобы проверить, открыт ли файл, можно вызвать функцию хв ореп(), являющуюся членом класса вяеееааь 1вяехеав и оеяевеав Она имеет следующий прототип. ф Ьоо1 хя орел() Если поток связан с открытым файлом, эта функция возвращает значение екпе, в противном случае она возвращает значение Ва1ве. Например, следующий фрагмент проверяет, открыт ли файл, связанный с потоком вуяехеавь 1Х(!вуяггеав.фя преп()) ( соне « "Файл не открыт.1п"; // Чтобы закрыть файл, следует вызвать функцию с1ове().
Например, чтобы закрыть файл, связанный с потоком вувехеав, можно применить следующим оператор. й вуясхеав.с1ояе(); Функция с1ояе() не имеет параметров и не возвращает никаких значений. Чтение и запись текстовых файлов Чтение и запись текстовых файлов осуществляются очень легко. Для этопз достаточно применить операторы "«" и "»", как это обычно делается для консольного ввода-вывода, только вместо потоков схп и соне необходимо подставить поток, связанный с файлом. Например, следую)цая программа создает короткий файл, содержащий название предмета и его стоимость.
$1пс1иг)е <1оясхеав> 41пс1иг)е <йяехеав> анапа павеярасе яео; 1пс ва1п() ( огяслеав оис('хиласу"); // текстовый файл для вывода. 11 ( )оиш ( соис « "невозможно открыть файл 1)г/дитоиу.1п"; хеецхп 1: ) осе « "Радиоприемники " « 39.95 « епс(1) опе « Тостеры " « 19.95 « еп<)1; оцс « "Миксеры " « 24.80 « епс)1; оис.с1ояе()," хеепхп О; ) Программа, приведенная ниже, считывает файл, созланный предыдущей программой, и выводит его содержимое на экран.
| $1пс1иде <Тояехеав> В1пс1иг)е <Тяехеав> ояфпд павеярасе яЫ) Часть й. Язык С++ хпс мазп() ( 1тяехеам 1п("1нуБтну"); уу Ввод И (.'Тп) ( санс с< "Невозможно открыть файл 1И'УЕБТОяу.тп"; хехпхп 1; ) снах 1еет[20) 11оас саяе; 1п » 1еем » саяе; саид « 1еегп сс " ' « соях « "1п"; 1п » 1ее3п » саяе; соис «1хем « " " «саяе « "1п"; хп» 1ееж» сове; сопх « 1еем « " " « саяе « "1п"; ).п.с1ояе(); хеспхп О; ) Чтение и запись файлов с помощью операторов "«" и '»" напоминает применение функций срхзпес() и свсапс() из языка с.
Формат записей в файле ничем не отличается от форгяата вывода на экран. Рассмотрим еще один пример работы с файлами на жестком диске. Эта программа считывает строки, введенные с клавиатуры, и записывает их на диск. Программа останавливается, если пользователь ввел знак восклицания. При вызове программы следует указать в командной строке имя файла, предназначенного дяя вывода. С1пс1ис)е <1ояехеав> Фйпс1иде <Тясхеппп> незло памеярасе яег); 1пх ва1п(1пс ахдс, сЬах *ахом[)) ( 11(ахдс)=2) самс « "Выяов: андрис <имя файла>1п"; хееихп 1; ) оуяххеаж опе(ахоч(1)); // Текстовый Файл для вывода. 11()опе) сапе <с "Неяояможно открыть файл для вывода. (п хегпхп 1; ) снах ясх[80); соне « зались строк па жесткий диск.1 для прекражения рабаты введите восклицательный знак.1п"; до [ санс <с суп » яех; опс сс яех <с епг)1у мп11е (*яхх )= '('); Глава 2(.
файловая система опс.с)ове(); гегагг, 0; ) Считывая файлы с помощью оператора "»", имейте в виду, что некоторые символы при вволе трансформируются. Например, разделители игнорируются. Чтобы предотвратить преобразование символов при чтении, файл следует открыть в бинарном режиме и применить функции, описанные в следующем разделе. Если при вводе достигается конец файла, потоку, связанному с файлом, присваивается значение да1ае.
(Эта ситуация иллюстрируется в следующем разделе.) ~~-3 ~~ Бесформатный и бинарный ввод-вывод Итак, чтение и запись форматированных текстовых файлов не вызывает никаких затрулнений. хотя это не самый эффективный способ работы с файлами. Кроме того, иногда возникает необходимость хранить бесформатные данные, а не текст, Рассмотрим функции, предназначенные для работы с хакими данными. Выполняя с фаилом бинарные операции, следует убедиться, что он открыл в режиме хоаю з)з1еагу.
Бесформатные данные могут храниться и в текстовом файле, но в этом случае при чтении некоторые символы будут преобразованы Бинарные файлы применяются именно для того, чтобы этого избежать. Сравнение символов и байтов При изучении бесформатного ввода-вывода необходимо учитывать следующее. Многие годы ввод-вывод в языках С и С++ был бойтовым (Ьуге опеп(ед). Это происходило потому, что символ (сйаг) является эквивалентом байта, и потоки ввода- вывода были символьными. Однако с появлением расширенных символов (ес)заг с) и связанных с ними потоков систему ввода-вывода языка С++ нельзя назвать байтовой. Теперь ее следует называз-ь сямвольной (сйагас(ег опеп(ед).
Разумеется, потоки обычных символов (сваг) остаются байтовыми, особенно при обработке нетекстовых данных. Однако эквивалентность понятий "символ" и "байт" больше не гарантируется. Как указывалось в главе 20, в книге используются только символьные (т.е. байтовыс) потоки, поскольку они наиболее широко распространены. Они обеспечивают более простую обработку бесформатных файлов, так как символьные потоки сохраняют однозначное соответствие между символами и байтами.
ФУНКЦИИ Р(ЙО И 9ЕьЦ Один из способов чтения и записи бесформатных файлов основан на применении функций рос() и аесО. Эти функции оперируют символами. Точнее говоря, функция пес() считывает символ, а функция рис() — записывает его. Разумеется, если фаил открыт в бинарном режиме, то при считывании символа (а не расширенного символа), эти функции считывают и записывают байты. Функция пес() имеет несколько форм, однако чаще всего используется ее следующая версия."Класс:ох(геаокфункция-член:рц(" 1всгеав Ьдсс(сйаг ЬсЫ овггеае яраг(спаг сй) Функция асс() считывает отлельный символ из потока и записывает его в переменную с)ь Кроме того, функция дес() возвращает ссылку на поток. Функция рис() записывает переменную сй в поток и возвращает ссылку на поток.
Часть!!. Язык С++ Следующая программа отображает на экране содержимое любого файла (как текстового, так и бинарного). Для считывания данных она использует функцию дее () . «1пс1иде <1ояхтеаы> 61пс1ибе <тяехеаз> ияйпд пап!еярасе яхб! 1пт иа1п(1пх ахдс, спат *атди[]) ( спат сй; 11(ахдс!>2] [ соих « "вызов: Рд <имя файла>1п"; тесихп 1! ) 11ястеаы 1п(атос[1]. зоя".:1п [ 1оя::Ььпаху] 11(]ьп) ( соие « '?!евозможио открыть файл."! теситп 1; ) ыЬ11е(1п) ( // Если достигнут конец файла, // значение объекта 1п равно та1яе.
1п. дет (сЫ; 11(1п) сове « сп! ) хехитп О; ) Как указывалось в предыдущем разлеле, по достижении конца файла поток, связанный с этим файлом, принимает значение еа1ве. Следовательно, рано или поздно объект хп примет значение еа1ве, и выполнение цикла ыь11е прекратится.
Приведенный выше цикл можно записать короче. ыЬ11е(1п.дех(сЫ ) соис «сЫ Этот фрагл!ент является правильным, поскольку функция дев () возвращает ссылку на поток хп, который примет значение еа1ве при обнаружении конца файла. В следующей программе для записи,в файл СНАКБ всех символов от 0 до 255 применяется функция рис(]. Как известно, символы АБСП занимают лишь половину из возможных значений типа сиат Остальные символы, как правило, называются ряс]ннренныз!и (ех(еп!)ег) с)]атас(ег яе!).
К ним относятся буквы национальных алфавитов и математические знаки. (Некоторые системы не поддерживают расширенные символы.) «1пс1иде <1оястеат> В1пс1ибе <Еяетеаи> ияьпд паыеярасе ях<)! 1пг. ыа?п() 1пс 1! ойястеал! оис("СНАРЯ", 1оя::оих [ 1оя::Ььпату)! 11()оих) ( спит « "невозможно открыть файл. хп"! Глава 21. Файловая система 6 хеспхп 1; // Записать символы на диск. Хох(1=0; 1<256; х++) сох.рпс((сйах.) 1); $ опх.с1ояе()г хеспхп 0; й) С помогцью этой программы можно проворить, поддерживает ли ваш компьютер расширснныс символьь Функции геаб() и игйе9 блоки бинарных данных можно считывать с помощью функций хеай() и ит1се().
Их прототипы выглялят слсдуюшим образом. хяххеаы ахеас) (снах "ан/; яххеазля1хе ншн); 1яохеат анх1хе(сонях свах "аи/, яххеаыязхе гнал); Функция хааа считывает ли/л символов из потока и записывает их в буфер, на который ссылается указатель ли/. Функция мхдсе записывает ли/л символов в поток, считывая их из буфера, на который ссылается указатель //и/' .Как разъяснялось в прсдыдушсй главе, тип ясхеаеяаяе определен в библиотскс как разновидность типа 1пс. Он позволяет хранить максимальнос количество символов, которые могуг преобразовываться при выполнении операций виола-вывода. Слсдуюшая программа записывает структуру на диск, а затем считывает сс обрашо. а1пс1пг)е <1ояххеат> 61пс1иг)е <бяххеаи> ()1пс1иг)е <сясх1пд> пя1по паыеярасе ясс)/ ясхпсс ясагпя ( снах пате(00]г ооггЬ1е Ьа1апсе; спя1спег) 1опд ассоппх псы; ): тих ваха ( ) ясхпсс ясахня асс; яххсру(асс.пате, "Ральф Трактор")/ асс.Ьа1апсе = 1123.23; асс ассоппх пюп = 34235бтв; // Записываем данные обяххеат опсЬа1("Ьа1апсе", хоя::оьс ~ хоь"::Ь1паху); 1б(!оисЬа1) ( сопя « "Невозможно открыть файл.хп"г хеспхп 1; опсЬа1.ых1се((снах *) аасс, яйяеоб(ясхпсв ясавпя)); опсЬа1.с1ояе(); Часть И.
Язык С++ // Считываем данные вновь зхбвстеам з.пЬа1( Ьа1апсе", зовззхп ~ з.ов:збвпату) хГ (! ЬпЬа1) ( соип « "Невозможно открыть файл.1п"; тевитп 1; ) хпЬа1.теаб((снах *) «асс, вхгеой(ввтисп ввавив)) соив « асс.папзе « епб1з соис « "счет $ ' « асс.ассоипс пипи соис.ртесхвхоп(2); свис.весб(ховззИкеб); соип « епа1 « "Баланс: б" « асс.Ьа1апсез хпЬа1.с1ове()з тевигп бз ) Как видим, для считывания илн записи целой структуры достаточно олного вызова функции кваб() или мтхсе(). Отдельное поле структуры невозможно считать или записать отдельно.