Г. Шилтд - Самоучитель C++ (PDF) (1114887), страница 42
Текст из файла (страница 42)
Это предотвращает игнорирование начальныхпробелов.3. В следующей программе для записи строки и числа типа double в файл testиспользуется функция wtite():^include <iostreain>#include <fstream>#include <cstring>using namespace std;int main (){ofstream out{"test", ios:rout I ios:ibinary};if(lout) {cout « "Файл открыть невозможноХп";return 1;}double num = 100.45;char str[] = "Это проверка";286Самоучитель C++out.write((char *) &num, sizeof(double));out.write(str, strlen(str));out.close{):return 0;Приведение типа к (char*) при вызове функции write() необходимо, еслибуфер вывода не определен как символьный массив.
Поскольку в C++ осуществляется строгий контроль типов, указатель на один тип не преобразуется автоматически в указатель на другой тип.4. В следующей программе для считывания из файла, созданного в программепримера 3, используется функция read():^include <iostream>^include <fstreairt>using namespace std;\int main ( ){ifstream in("test", i o s : : i n | ios : :binary) ;cout « "Файл открыть невозможно \п";return 1;double num;char str[80];in.read( {char *) &num, sizeof (double) );in. read(str, 15) ;str[14] = '\0',cout « num « ' ' « str;in.
close () ;return 0;Как и в программе из предыдущего примера, приведение типов внутрифункции read() необходимо, поскольку в C++ указатель одного типа автоматически не преобразуется в указатель другого типа.Глава 9. Дополнительные возможности ввода/вывода в C++2875. В следующей программе сначала массив double записывается в файл, а затемсчитывается обратно.
Кроме того, отображается число считанных символов.// Демонстрация работы функции gcountO^include <iostream>ttinclude <fstrearn>using namespace std;int main()ofstream out ("test", ios::out | ios: :binary) ;if (lout) {cout « "Файл открыть невозможно\п";return 1 ;double nums[4] = {1.1, 2.2, 3.3, 4.4};out.write((char *) nums, sizeof(nums));out. close (} ;ifstream in("test", ios::in | ios::binary);if(!in) {cout « "Файл открыть невозможной";return 1;'in.read((char *) snums, sizeof(nums));int i;for (i=0; i<4; i++)cout « numsfi] « ' ';cout « '\n';cout « in.gcount() « " символов считано\n";in.close ();return 0;}УпраЖненш^'•"••••——S^p1.
Измените ответы на упражнения 1 и 3 раздела 9.2 так, чтобы в них использовались функции get(), put(), read() и/или write(). (Используйте эти функциитам, где они, по вашему мнению, принесут наибольшую отдачу.)288Самоучитель C++2. Дан следующий класс. Напишите программу для вывода содержимого классав файл. Для этой цели создайте пользовательскую функцию вывода.class account {int custnum;char name[80];double balance;public:account(int c, char *n, double b}custnum = c;strcpyiname, n);balance = b;// здесь нужна пользовательская функция вывода};9.4. Дополнительная информацияо функциях двоичного ввода/выводаКроме представленной ранее формы, функцию get() можно перегрузить ещенесколькими способами.
Здесь показаны прототипы трех наиболее частоперегружаемых форм:iatream figet(char *буфвр, strearasize чксло_байт);istream figet (char *буфер, strearasize число__баит,char ограничитель) ;int get();Первая функция get() считывает символы в массив, определенный указателем буфер, до тех пор, пока либо не считано столько символов, сколько задано параметром число_байт — I, либо не встретился символ конца файла.В конце массива, заданного указателем буфер, функция get() помещает ноль.Если в потоке ввода встретится символ новой строки, он не извлекается, аостается в потоке до следующей операции ввода.Вторая функция get() считывает символы в массив, определенный указателем буфер, до тех пор, пока либо не считано столько символов, сколько задано параметром число_байт — 1, либо не встретился символ, заданныйпараметром ограничитель, либо не встретился символ конца файла.
В концемассива, заданного указателем буфер, функция get() помешает ноль. Если впотоке ввода встретится символ ограничитель, он не извлекается, а остаетсяв потоке до следующей операции ввода.Третья функция get() возвращает из потока следующий символ. Она возвращает символ EOF, если достигнут конец файла. Эта форма функцииget() напоминает функцию getc() языка С.Глава 9.
Дополнительные возможности ввода/вывода в C++289Другой функцией для реализации ввода является функция getline(). Этафункция — член всех потоковых классов ввода. Ниже показаны ее прототипы:istream figetline(char *буфер, streamsize число_байт);istream ugetline(char * буфер, streamsize число байт,char ограничитель) ;Первая функция считывает символы в массив, обозначенный указателембуфер, до тех пор, пока либо не считано столько символов, сколько заданопараметром число_байт — 1, либо не встретился символ новой строки, либоне встретился символ конца файла. В конце массива, заданного указателембуфер, функция getline() помещает ноль.
Если в потоке ввода встретитсясимвол новой строки, он извлекается, но не помещается в массив.Вторая функция считывает символы в массив, обозначенный указателем буфер, до тех пор, пока либо не считано столько символов, сколько заданопараметром число_байт — 1, либо не встретился символ ограничитель, либоне встретился символ конца файла. В конце массива, заданного указателембуфер, функция getline() помещает ноль. Если в потоке ввода встретитсясимвол ограничитель, он извлекается, но не помещается в массив.Как можно заметить, обе версии функции getlineQ фактически тождественны версиям get(5y$ep, число_байт) и %еЬ(буфер9 число_байт, ограничитель)функции get().
Обе считывают символы из потока ввода и помещают их вмассив, обозначенный указателем буфер до тех пор, пока либо не считаночисло_байт — 1 символов, либо не встретился символ ограничитель илисимвол конца файла. Отличие между функциями get() и getline() в том, чтофункция gellineQ считывает и удаляет из потока ввода символ ограничитель,а функция get() — нет.Используя функцию peek(), можно получить следующий символ из потокаввода без его удаления из потока. Функция является членом потоковыхклассов ввода и имеет следующий прототип:int peek();Функция возвращает следующий символ из потока или, если достигнут конец файла, символ EOF.С помощью функции putbackQ, являющейся членом потоковых классовввода, можно возвратить последний считанный из потока символ обратно впоток. Ниже показан прототип этой функции:istream fiputback (char с);Здесь с — это последний считанный из потока символ.При выполнении вывода данные не сразу записываются на связанное спотоком физическое устройство, а информация временно сохраняется вовнутреннем буфере.
Только после заполнения буфера его содержимое переписывается на диск. Однако вызов функции flush () вызывает физическуюСамоучитель C++290запись информации на диск до заполнения буфера. Ниже показан прототипфункции flush(), являющейся членом потоковых классов вывода:ostream fiflushO ;Вызовы функции flush() оправданы при работе в неблагоприятной обстановке (например, в ситуациях, когда часто случаются сбои по питанию).I.
Как вы знаете, при использовании для считывания строки оператора »,считывание прекращается при встрече первого разделительного символа.При наличии в строке пробелов такое считывание становится невозможным.Однако, как показано в программе, с помощью функции gctlinc() можно решить эту проблему:// Использование функции getlineO для считывания строки с пробелами# include <iostream>ftinclude <fstream>using namespace std;intmain()char str [80];cout « "Введите ваше имя: ";cin.getline (str, 79} ;cout « str « ' \ n ' ;return 0;В данном случае ограничителем для функции getline() является символ новойстроки.
Это делает выполнение функции getline() очень похожей на выполнение стандартной функции gets().2. В реальном программировании особенно полезны функции peek() иputback() Они позволяют упростить управление, когда неизвестен тип вводимой в каждый конкретный момент времени информации. Следующаяпрограмма иллюстрирует это. В ней из файла считываются строки либо целые. Строки и целые могут следовать в любом порядке.// Демонстрация работы функции p e e k ( )^include <iostream>ttinclude <fstream>#include <cctype>using namespace std;int main ()Глава 9.
Дополнительные возможности ввода/вывода в C++(291char ch;ofstream out("test", ios::out | ios::binary);.if(lout) {cout « "Файл открыть невоэможно\п";return 1;}char str[80], *p;out « 123 « "this is a test" « 23;out « "Hello there!" « 99 « "sdf" « endl;out.close{);ifstream inC'test", ios::in | ios: :binary);if(!in) {cout « "Файл открыть невозможнсЛп";return 1;}do {p = str;ch = in.peekj); // выяснение типа следующего символаif(isdigit(ch)) {while(isdigit{*p=in.get())} p++; // считывание целогоin.putback(*p); // возврат символа в поток*р = '\0'; // заканчиваем строку нулемcout « "Целое: " « atoi(str);}else if(isalpha(ch)} { // считывание строкиwhile(isalpha(*p=in.get())) p++;in.putback(*p); // возврат символа в поток*р - '\0'; // заканчиваем строку нулемcout « "Строка: " « str;}else in.getO; // пропускcout « '\n';} while(lin.eof());in.close();return 0;1.