Паппас К., Мюррей У. - Visual C++ 6. Руководство разработчика - 2000
.pdfosout<< " " << client .pszphone;
}
Тогда для вывода содержимого структуры client на экран достаточно будет задать такое выражение:
cout << client;
Эффективность этих операторов объясняется компактностью поддерживающего их программного кода. При обращении к функциям типа printf() и scanf() задействуется большой объем кода, основная часть которого не используется при выполнении конкретной операции ввода или вывода данных. Даже если в языке С вы оперируете только целыми числами, все равно будет подгружаться весь код функции с блоками обработки данных самых разных типов. Напротив, в языке C++ реально подгружаться будут только те подпрограммы, которые необходимы для решения конкретной задачи.
В следующей программе оператор >> применяется для чтения данных различных типов:
//
//insert. срр
//Эта программа на языке C++ демонстрирует применение оператора >>
для
//ввода данных типа char, int и double, а также строк.
//
#include <iostream.h> #define INUMCHARS. 45 #define INULL_CHAR 1 void main(void) { char canswer;
int ivalue; double dvalue;
char рзгпагае[INUMCHARS + INULL_CHAR];
pout<< "Эта программа позволяет вводить данные различных типов.\n"; cout<< "Хотите попробовать? (Y— да, N — нет) ";
cin >> canswer;
if (canswer == 'У'){
cout << "\n"<< "Введите целое число: "; cin >> ivalue;
cout<< "\n\nВведите число с плавающей запятой: "; cin >> dvalue; cout<< "\n\nВведите ваше имя: "; cin >> pszname; cout<< "\n\n"; } }
В данном примере оператор << используется в простейшем виде — для вывода текста приглашений. Обратите внимание, что оператор >> выглядит во всех случаях одинаково, если не считать имен переменных.
Теперь приведем пример программы, в которой оператор << применяется для вывода данных различных типов:
//
I/ extract.срр
//Эта программа на языке C++ демонстрирует применение оператора <<
для
//вывода данных типа int, float, а также строк.
//
#include <iostream.h> void main (void)
{
char description!] = "Магнитофон"; int quantity = 40;
float price = 45.67;
cout<< "Наименование товара: " << description<< endl;
201
cout<< |
"Количество на складе: " << quantity<< endl; |
cout<< |
"Цена в долларах: " << price<< endl; |
} |
|
Программа выведет на экран следующую информацию:
Наименование товара: Магнитофон Количество на складе: 40 Цена в долларах: 45.67
Здесь следует обратить внимание на манипулятор endl. Манипуляторами называются специальные функции, которые в выражениях с потоковыми объектами, такими как coutи cin, записываются подобно обычным переменным, но в действительности выполняют определенные действия над потоком. Манипулятор endlшироко применяется при выводе данных в интерактивных программах, так как помимо записи символа новой строки он очищает буфер потока, вызывая "выталкивание" содержащихся в нем данных. Эту же операцию, но без вывода символа \n, можно выполнить с помощью манипулятора flush.
Рассмотрим некоторые особенности ввода-вывода строк:
//
//string. срр
//Эта программа на языке C++ иллюстрирует особенности
//работы оператора >> со строками.
//
#include <iostream.h> #define INUMCHARS 45 #define INULL_CHARACTER 1 void main (void) {
char ps zname[ INUMCHARS + INULL_CHARACTER] ; cout<< "Введите ваше имя и фамилию: ";
cin >> pszname;
cout << "\n\nСпасибо, " << pszname;
В результате выполнения программы будет выведена следующая информация:
Введите ваши имя и фамилию: Александр Иванов Спасибо, Александр
Почему не была выведена вся строка? Это связано с особенностью оператора >>: он прекращает чтение строки, как только встречает первый пробел, знак табуляции или символ новой строки (кроме ведущих). Поэтому в переменной pszname сохранилось только имя, но не фамилия. Чтобы решить эту проблему, следует воспользоваться функцией cin.get (), как показано ниже:
//
//cinget.cpp
//Эта программа на языке C++ демонстрирует применение оператора >>
//совместно с функцией get()для ввода строк с пробелами.
// |
|
|
#include <iostream.h> |
. |
|
#define.INUMCHARS 45 |
||
j#define |
INULL_CHARACTER |
1 |
void main(void)
char pszname[INUMCHARS + INULL CHARACTER]; cout<< "Введите ваше имя и фамилию: "; cin.get(pszname, INUMCHARS);
cout << "\n\nСпасибо, " << pszname;
Теперь программа отобразит данные следующим образом:
Введите ваше имя и фамилию: Александр Иванов Спасибо, Александр Иванов
202
Функция cin .get (), помимо имени переменной, принимающей данные, ожидает два дополнительных аргумента: максимальное число вводимых символов и символ, служащий признаком конца ввода. В качестве последнего по умолчанию используется символ \n. Функция cin.get() считывает все символы в строке, включая пробелы и знаки табуляции, пока не будет прочитано указанное число символов или не встретится символ-ограничитель. Если в качестве ограничителя необходимо, к примеру, использовать знак *, следует записать такое выражение:
cin.get(pszname, INUMCHARS, '*');
Флаги и функции форматирования
Работа всех потоковых объектов из библиотеки IOSTREAM.H контролируется флагами форматирования, определяющими такие параметры, как, например, основание системы счисления при выводе целых чисел и точность представления чисел с плавающей запятой.
Флаги можно устанавливать с помощью функции setf(), а сбрасывать — с помощью функции unsetf (). Есть два варианта функции setf() с одним аргументом типа long и с двумя. Первым аргументом является набор флагов, объединенных с помощью операции побитового ИЛИ (|). Возможные флаги перечислены в таблице 11.1.
Таблица 11.1. Флаги форматирования
Флаг |
Назначение |
|
|
|
|
skipws |
при вводе пробельные литеры пропускаются |
|
|
|
|
left |
выводимые данные выравниваются по левому краю с дополнением символами-заполнителями по |
|
ширине поля |
||
|
||
|
|
|
right |
выводимые данные выравниваются по правому краю с дополнением символами-заполнителями по |
|
ширине поля (установлен по умолчанию) |
||
|
||
|
|
|
internal |
при выравнивании символы-заполнители вставляются между символом знака или префиксом основания |
|
системы счисления и числом |
||
|
||
|
|
|
dec |
целые числа выводятся по основанию 10 (установлен по умолчанию); устанавливается также |
|
манипулятором dec |
||
|
||
|
|
|
oct |
целые числа выводятся по основанию 8; устанавливается также манипулятором oct |
|
|
|
|
hex |
целые числа выводятся по основанию 16; устанавливается также манипулятором hex |
|
|
|
|
|
||
showbase |
при выводе целых чисел отображается префикс, указывающий на основание системы счисления |
|
|
|
|
showpoint |
при выводе чисел с плавающей запятой всегда отображается десятичная точка, а хвостовые нули не |
|
отбрасываются |
||
|
|
|
uppercase |
шестнадцатеричные цифры от А до F, а также символ экспоненты Е отображаются в верхнем регистре |
|
|
|
|
showpos |
при выводе положительных чисел отображается знак плюс |
|
|
|
|
|
|
|
scientific |
числа с плавающей запятой отображаются в научном формате (с экспонентой) |
|
|
|
|
fixed |
числа с плавающей запятой отображаются в фиксированном формате (без экспоненты) |
|
|
|
|
unitbuf |
при каждой операции вывода буфер потока должен очищаться |
|
|
|
|
stdio |
при каждой операции вывода буферы потоков stdout и stderr должны очищаться |
Вторым аргументом является специальная битовая маска, определяющая, какую группу флагов можно модифицировать. Имеются три стандартные маски:
adjustfield = internal | left | right basefield = dec | oct | hex floatfield = fixed | scientific
Оба варианта функции setf() возвращают значение типа long, содержащее предыдущие установки всех флагов.
Все перечисленные флаги, а также константы битовых масок и упоминавшиеся манипуляторы dec, hexи octявляются членами класса ios - базового в иерархии всех классов ввода-вывода. В этот класс входят, помимо прочего, функции fill() , precision ( ) и width ( ) , тоже связанные с форматированием выводимых данных!
Функция fill( ) устанавливает переданный ей символ в качестве символа-заполнителя. Аналогичные действия выполняет манипулятор setfill () . Вызванная без аргументов, функция возвращает текущий символ-заполнитель. По умолчанию таковым служит пробел.
203
Когда установлен флаг scientificили fixed, функция precision() задает точность представления чисел с плавающей запятой, в противном случае определяет общее количество значащих цифр. Аналогичные действия выполняет манипулятор setprecision() . По умолчанию точность равна 6. Вызванная без аргументов, функция возвращает текущее значение точности.
Функция width() определяет минимальную ширину поля вывода в символах. Если при выводе количество символов оказывается меньшим ширины поля, оно дополняется специальными символами-заполнителями. После каждой операции записи значение ширины поля сбрасывается в 0. Аналогичные действия выполняет манипулятор setw( ) . Вызванная без аргументов, функция возвращает текущую ширину поля.
Манипуляторы setfill () , setprecision() и setw(), также являющиеся членами класса ios, относятся к категории параметризованных, и для работы с ними необходимо дополнительно подключить к программе файл IOMANIP.H.
Следующая программа является написанным на C++ аналогом программы printf.c, рассмотренной в предыдущей главе.
//ioflags.cpp
//Эта программа на языке C++ демонстрирует применение
//флагов и функций форматирования.
#include <strstrea.h>
#define MAX_LENGTH 20 void row (void); main{) {
char |
с = 'A',psz[] = "Строка для экспериментов", |
strbuffer[MAX_LENGTH]; |
|
int |
ivalue = 1234; |
double dPi = 3.14159265;
//вывод символа с row(); // [ 1] cout<< с;
//вывод ASCII-кода символа с row() ; // [2]
cout << (int)c;
//вывод символа с ASCII-кодом 90 row (); // [ 3]
cout << (char)90;
//вывод значения ivalue в восьмеричной системе row(); //[4]
cout << oct << ivalue;
//вывод значения ivalue в шестнадцатеричной системе //сбуквами в нижнем регистре
row (); // [5]
cout << hex << ivalue;
//вывод значения ivalue в шестнадцатеричной системе
//с буквами в верхнем регистре
row (); // [ 6] cout.setf(ios::uppercase); cout << hex << ivalue;
cout.unsetf(ios::uppercase); // отмена верхнего регистра символов cout<< dec; // возврат к десятичной системе
//вывод одного символа, минимальная ширина поля равна 5,
//выравнивание вправо с дополнением пробелами
row();// [ 7] cout.width(5); cout<< с;
//вывод одного символа, минимальная ширина поля равна 5,
//выравнивание влево с дополнением пробелами
row(); // [ 8] cout.width(5); cout.setf(ios::left); cout << c; cout.unsetf(ios::left);
204
//вывод строки, отображаются 24 символа row();// [9] cout<< psz;
//вывод минимум 5-ти символов строки row();// [10] cout.width(5); cout<< psz;
//вывод минимум 38-ми символов строки,
//выравнивание вправо с дополнением пробелами row();// [11]
cout.width(38); cout << psz;
//вывод минимум 38-ми символов строки,
//выравнивание влево с дополнением пробелами row ();// [12]
cout.width(38);
cout.setf(ios::left); cout << psz; cout.unsetf(ios::left);
//вывод значения ivalue, по умолчанию отображаются 4 цифры row();// [13] cout<< ivalue;
//вывод значения ivalue со знаком row ();// [14] cout.setf(ios::showpos);
cout << ivalue; cout.unsetf(ios::showpos) ;
//вывод значения ivalue минимумиз 3-х цифр, отображаются 4 цифры row ();// [15]
cout.width(3); cout << ivalue;
//вывод значения ivalue минимум из 10-ти цифр,
} // выравнивание вправо с дополнением пробелами row();// [16]
cout.width(10); cout<< ivalue;
//вывод значения ivalue минимум из 10-ти цифр,
//выравнивание влево с дополнением пробелами row();// [17]
cout.width(10); cout.setf(ios::left) ; cout << ivalue; cout.unsetf(ios::left);
//вывод значения ivalue минимум из 10-ти цифр,
//выравнивание вправо с дополнением нулями row (); // [18]
cout.width (10); cout.fill ('0'); cout << ivalue; cout.fill (' ');
//вывод значения dPiс форматированием по умолчанию row(); // [19]
cout<< dPi;
//вывод значения dPi, минимальная ширина поля равна 20,
//выравнивание вправо с дополнением пробелами
row{); // [20]
cout.width (20); cout<< dPi;
//вывод значения dPi, минимальная ширина поля равна 20,
//выравнивание вправо с дополнением нулями
row();// [21] cout.width(20); cout.fill('0'); cout << dPi; cout. fill (' ');
//вывод значения dPi, минимальная ширина поля равна 20,
//выравнивание влево с дополнением пробелами
205
row();// [22] cout.width(20); cout.setf(ios::left) ; cout<< dPi;
// вывод значения dPi, минимальная ширина поля равна 20,
//выравнивание влево с дополнением нулями row();// [23]
cout.width(20); cout. fill ('0'); cout << dPi;
cout.unsetf(ios::left); cout.fill(' ');
//вывод 19-ти символов строки, минимальная ширина поля равна 19 row();// [24]
ostrstream(strbuffer, 20).write(psz,19)<< ends; cout.width(19);
cout << strbuffer;
//вывод первых двух символов строки
row(); // [25]
ostrstream(strbuffer, 3).write(psz,2) << ends; cout<< strbuffer;
//вывод первых двух символов строки, минимальная ширина поля равна 19,
//выравнивание вправо с дополнением пробелами
row();// [26] cout.width(19); cout << strbuffer;
//вывод первых двух символов строки, минимальная ширина поля равна 19,
//выравнивание влево с дополнением пробелами row();// [27] cout.width(19); cout .setf (ios :: left) ; cout << strbuffer; cout .unsetf (ios :: left) ;
//вывод значенияdPi из5-ти значащих цифр
row ();// [28]
cout .precision (9); cout << dPi;
//вывод значения dPiиз 2-х значащих цифр, минимальная ширина поля
//равна 20, выравнивание вправо с дополнением пробелами
row ();// [29] cout. width (20) ; cout .precision (2); cout << dPi;
//выводзначенияdPi из 4-хзначащихцифр row () ; // [30]
cout .precision (4); cout << dPi;
//вывод значения dPi из 4-х значащих цифр, минимальная ширина поля
//равна 20, выравнивание вправо с дополнением пробелами
row(); // [31]
cout. width(20); cout<< dPi;
//вывод значения dPi, минимальная ширина поля равна 20,
//4 цифры после десятичной точки, выравнивание вправо IIс дополнением пробелами, научный формат (с экспонентой) row ();// [32]
cout . setf (ios :: scientific) ; cout. width ( 20 );
cout << dPi;
cout. unset f (ios: : scientific ); return (0);
}
void row(void) { static int In = 0; cout << " \n ["; cout.width(2) ; cout<< ++ln<< "] "; }
Результат работы программы будет выглядеть следующим образом:
206
[ 1] |
А |
[ 2] |
65 |
[ 3] |
Z |
[ 4] |
2322 |
[ 5] |
4d2 |
[ 6] |
4D2 |
[ 7]А |
|
[ 8]А |
Строка для экспериментов |
[ 9] |
|
[10] |
Строка для экспериментов |
[11]' |
Строка для экспериментов |
[12]Строка для экспериментов
[13]1234
[14]+1234
[15]1234
[16]1234
[17]1234
[18]0000001234
[19]3.14159
[20]3.14159
[21]00000000000003.14159
[22]3.14159
[23]3.141590000000000000
[24]Строка для эксперим
[25]Ст
[26]Ст
[27]Ст
[28]3.14159265
[29]3.1
[30]3.142
[31]3.142
[32] 3.1416e+000
В этой программе следует обратить внимание на использование класса ostrstream в пунктах 24 и 25, а также неявно в пунктах 26 и 27. Этот класс управляет выводом строк. Необходимость в нем возникла в связи с тем, что флаги форматирования оказывают влияние на работу оператора <<, но не функции write() класса ostream(класс ostrstream является его потомком и наследует данную функцию), которая записывает в поток указанное число символов строки. Выводимые ею данные всегда прижимаются к левому краю. Поэтому мы поступаем следующим образом:
ostrstream(strbuffer, 20).write(psz,19)<< ends; cout.width(19); cout << strbuffer;
Разберем этот фрагмент шаг за шагом. Сначала вызывается конструктор класса ostrstream, создающий временный безымянный объект данного класса, автоматически уничтожаемый по завершении строки. Если вы еще не знакомы с понятием конструктора, то поясним, что это особая функция, предназначенная для динамического создания объектов своего класса. Конструктор класса ostrstreamтребует указания двух аргументов: буферной строки, в которую будет осуществляться вывод, и размера буфера. Особенность заключается в том, что реальный размер буферного массива может быть больше указанного, но все данные, записываемые сверх лимита, будут отсекаться.
Итак, конструктор создал требуемый объект, связанный с буфером strbuffer. Этот объект является обычным потоком в том смысле, что им можно управлять как и любым другим потоком вывода, только данные будут направляться не на экран, а в буфер. Вторым действием вызывается функция write() объекта, записывающая в поток первые 19 символов строки psz. Оператор точка (.) в данном случае обозначает операцию доступа к члену класса. Здесь тоже есть своя особенность: функция write() возвращает адрес потока, из которого она была вызвана. А это, в свою очередь, означает, что мы можем тут же применить к потоку оператор
207
вывода <<. Итого, три действия в одном выражении! Манипулятор endsкласса ostreamвставляет в поток символ \0,служащий признаком завершения строки. Именно поэтому в буфере было зарезервировано 20 ячеек — на единицу больше, чем количество выводимых символов строки psz. В результате выполненных действий в буфере оказалась сформированной готовая строка, которая, в конце концов, и направляется в поток cout.
Теперь рассмотрим, что происходит в пункте 25:
ostrstream (strbuf fer, 3) .write (psz, 2) << ends; cout << strbuffer;
Последовательность действий та же, но резервируется не весь буфер, а только первые три ячейки. Трюк в том, что объект cout воспринимает массив strbuffer как обычную строку, но поскольку в третьей ячейке стоит символ \0,то получается, что строка состоит из двух символов! В пунктах 26 и 27 используется содержимое буфера, полученное в пункте 25.
Важно также помнить, что функция width( ) оказывает влияние только на следующий за ней оператор вывода, тогда как, например, действие функции precision() останется в силе до тех пор, пока она не будет выполнена снова либо не будет вызван манипулятор setprecision( ) .
Файловый ввод-вывод
Во всех программах на языке C++, рассмотренных до сих пор, для ввода и вывода данных применялись стандартные потоки cin и cout. Если для этих же целей удобнее работать с файлами, следует воспользоваться классами ifstream и ofstream, которые порождены от классов istream и ostream и унаследовали от них функции, соответственно, чтения и записи. Необходимо также подключить файл FSTREAM.H (он, в свою очередь, включает файл IOSTREAM.H). В следующей программе демонстрируется работа с файлами посредством классов ifstream и ofstream:
//
//fstream. cpp
//Эта программа на языке C++ демонстрирует, как создавать
//потоки ifstream и ofstream для обмена данными с файлом.
#include <fstream.h> int main(void) { char c;
ifstream ifsin("text.in", ios::in); if(lifsin) |
|||
cerr<< |
"\nНевозможно открыть |
файл |
text.in для чтения."; |
ofstream ofsout("text.out", |
ios::out); |
||
if(!ofsout) |
файл |
text.outдля записи."; |
|
cerr<< |
"\nНевозможно открыть |
||
while (ofsout && ifsin.get(c) |
) |
|
|
ofsout.put (c); |
|
|
|
if sin. close (); |
|
|
ofsout. close () ; return(0); }
Программа создает объект ifsin класса ifstream и связывает с ним файл TEXT. IN, находящийся в текущем каталоге. Всегда следует проверять доступность указанного файла. В данном случае проверка осуществляется достаточно оригинальным образом. Оператор ! в потоковых классах перегружен таким образом, что, будучи примененным к соответствующему объекту, при наличии каких-либо ошибок в потоке возвращает ненулевое значение. Аналогичным образом создается и объект ofsoutкласса ostream, связываемый с файлом TEXT.OUT.
В цикле whileосуществляется считывание и запись отдельных символов в выходной файл до тех пор, пока в ряду символов не попадется EOF. При завершении программы закрываются оба файла. Особенно важно закрыть файл, в который записывались данные, чтобы предупредить потерю информации, еще находящейся в буфере.
208
Иногда возникают ситуации, когда необходимо отложить процесс спецификации файла или когда с одним объектом нужно последовательно связать сразу несколько потоков. В следующем фрагменте показано, как это сделать:
ifstream ifsin;
.
.
.
ifsin.open("weekl.in");
.
.
.
if sin.close () ; ifsin.open("week2.in")
.
.
.
if sin. close () ;
Если необходимо изменить режим доступа к файлу, то это можно сделать путем модификации второго аргумента конструктора соответствующего файлового объекта, Например:
ofstream ofsout("file.out", ios::app | ios::nocreate);
В данном выражении делается попытка создать объект ofsout и связать его с файлом FILE.OUT. Поскольку указан флаг ios::nocreate, подключение не будет создано, если файл FILE.OUT не существует. Флаг ios::app означает, что все выводимые данные будут добавляться в конец файла. В следующей таблице перечислены флаги, которые можно использовать во втором аргументе конструкторов файловых потоков (допускается объединение флагов с помощью операции побитового ИЛИ):
Флаг |
Назначение |
ios: : in |
Файл открывается для чтения, его содержимое не очищается |
ios: : out |
Файл открывается для записи |
ios: : ate |
После создания объекта маркер текущей позиции устанавливается в конец файла |
ios: : арр |
Все выводимые данные добавляются в конец файла |
ios: : trunc |
Если файл существует, его содержимое очищается (автоматически устанавливается при |
|
открытии файла для записи) |
ios: : nocreate |
Объект не будет создан, если файл не существует |
ios: : noreplace |
Объект не будет создан, если файл существует |
ios: : binary |
Файл открывается в двоичном режиме (по умолчанию — в текстовом) |
Для обмена данными с файлом можно также использовать объект класса fstream. Например, в следующем выражении файл UPDATE.DATоткрывается для чтения и записи данных:
fstream io("update.dat", ios::in | ios::app);
К объектам класса iostream(а класс fstream является его потомком) можно применять функции seekg() и seekp(),позволяющие управлять положением маркера текущей позиции файла. Функция seekg() задает положение маркера, связанного с чтением данных из файла, а функция seekg() — с записью. Обе функции требуют указания одного или двух аргументов. Если указан один аргумент, он считается абсолютным адресом маркера. Если два, то первый задает относительное смещение, а второй — направление перемещения. Существует также функция tellg(), возвращающая текущее положение маркера чтения, и функция tellp(), возвращающая текущее положение маркера записи. Рассмотрим небольшой фрагмент программы:
streampos current_position = io.tellp(); io << objl << obj2 << obj3; io.seekp(current_position); io.seekp(sizeof(objl), ios::cur);
io<< newobj2;
Сначала создается указатель current_positionтипа streampos, который инициализируется текущим адресом маркера записи. Во второй строке в поток io записываются три объекта. В третьей строке с помощью функции seekp() указатель перемещается в сохраненную позицию.
209
Далее с помощью оператора sizeof() вычисляется объем памяти в байтах, занимаемый в файле объектом obj1, и функция seekp() "перескакивает" через него. В результате поверх объекта obj2 записывается объект newobj2.
Вторым аргументом функций seekg() и seekp() может быть один из следующих флагов: ios::beg(смещение на указанную величину от начала файла), ios: : cur(смещение на указанную величину от текущей позиции) и ios:: end (смещение на указанную величину от конца файла). Например, данное выражение переместит маркер чтения на 5 байтов от текущей позиции:
io.seekg(5, ios::cur);
Следующее выражение переместит маркер на 7 байтов от конца файла: io.seekg(-7, ios::end);
Определение состояния потока
С каждым потоком связана внутренняя переменная состояния. В случае возникновения ошибки устанавливаются определенные биты этой переменной в зависимости от категории ошибки. Общепринято, что если поток класса ostreamнаходится в ошибочном состоянии, то функции записи не выполняются и не меняют состояние потока. Существует ряд функций, позволяющих определить состояние потока:
Функция |
Действие |
|
|
eof() |
Возвращает ненулевое значение при обнаружении конца файла |
|
|
fail() |
Возвращает ненулевое значение в случае возникновения какой-либо ошибки в потоке, возможно не |
|
фатальной; если функция bad() при этом возвращает 0, то, скорее всего, можно продолжать работу |
|
с потоком, предварительно сбросив флаг ios:: failbit |
|
|
bad() |
Возвращает ненулевое значение в случае возникновения серьезной ошибки ввода-вывода; в этом |
|
случае продолжать работу с потоком не рекомендуется |
|
|
good() |
Возвращает ненулевое значение, если биты состояния не установлены |
|
|
rdstate() |
Возвращает текущее состояние потока в виде одной из констант: ios: :goodbit(нет ошибки), ios:: |
|
eofbit(достигнут конец файла), ios::failbit(возможно, некритическая ошибка форматирования или |
|
преобразования), ios: :badbit(критическая ошибка) |
|
|
clear() |
Задает состояние потока; принимает аргумент типа int, который по умолчанию равен 0, что |
|
соответствует сбросу всех битов состояния, в противном случае содержит одну или несколько |
|
перечисленных в предыдущем пункте констант, объединенных с помощью операции побитового |
|
ИЛИ (|) |
|
|
Приведем пример: ifstreampfsinfile("sample.dat", ios::in);
if (pfsinfile.eof ()) |
// состояние потока pfsinfile сбрасывается |
|
pfsinfile.clear() ; |
||
if (pfsinfile. fail () |
) |
|
cerr<< ">>> ошибка при |
создании |
файла sample.dat<<<"; |
if (pfsinfile. good ()) cin >> my_object; |
||
if(!pfsinfile) // другой способ |
обнаружения ошибки |
|
cout<< ">>> ошибка при |
создании |
файла sample.dat<<<"; |
210
- #13.08.201334.52 Mб91Липман С., Лажойе Ж., Му Б. - Язык программирования C++. Вводный курс - 2007.djvu
- #13.08.201347.18 Mб127Литвиненко Н.А. - Технология программирования на C++. Win32 API-приложения - 2010.djvu
- #
- #
- #13.08.201317.53 Mб103Оберг Р., Торстейсон П. - Архитектура .NET и программирование на Visual C++ - 2002.pdf
- #
- #
- #
- #
- #
- #