Бьерн Страуструп. Язык программирования С++ Второе дополненное издание



Pdf көрінісі
бет189/256
Дата11.07.2022
өлшемі2,87 Mb.
#37591
1   ...   185   186   187   188   189   190   191   192   ...   256
10.3.2 Состояния потока 
С каждым потоком (istream или ostream) связано определенное состояние. Нестандартные ситуации и 
ошибки обрабатываются с помощью проверки и установки состояния подходящим образом. Узнать 
состояние потока можно с помощью операций над классом ios: 
class ios { 
//ios является базовым для ostream и istream 
//... 
public: 
int 
eof() 
const; 
// дошли до конца файла 
int 
fail() 
const; 
// следующая операция будет неудачна 
int 
bad() 
const; 
// 
поток испорчен 
int 
good() 
const; 
// следующая операция будет успешной 
//... 
}; 
Последняя операция ввода считается успешной, если состояние задается good() или eof(). Если 
состояние задается good(), то последующая операция ввода может быть успешной, в противном случае 
она будет неудачной. Применение операции ввода к потоку в состоянии, задаваемом не good(), 
считается пустой операцией. Если произошла неудача при попытке чтения в переменную v, то значение 
v не изменилось (оно не изменится, если v имеет тип, управляемый функциями члена из istream или 


Бьерн Страуструп.
Язык программирования С++ 
 
264 
ostream). Различие между состояниями, задаваемыми как fail() или как bad() уловить трудно, и оно 
имеет смысл только для разработчиков операций ввода. Если состояние есть fail(), то считается, что 
поток не поврежден, и никакие символы не пропали; о состоянии bad() ничего сказать нельзя. 
Значения, обозначающие эти состояния, определены в классе ios: 
class ios { 
//... 
public: 
enum 
io_state 

goodbit=0, 
eofbit=1, 
filebit=2, 
badbit=4, 
}; 
//... 
}; 
 
Истинные значения состояний зависят от реализации, и указанные значения приведены только, чтобы 
избежать синтаксически неправильных конструкций. 
Проверять состояние потока можно следующим образом: 
switch (cin.rdstate()) { 
case 
ios::goodbit: 
// последняя операция с cin была успешной 
break; 
case 
ios::eofbit: 
// в конце файла 
break; 
case 
ios::filebit: 
// некоторый анализ ошибки 
// возможно неплохой 
break; 
case 
ios::badbit: 
// cin возможно испорчен 
break; 

В более ранних реализациях для значений состояний использовались глобальные имена. Это 
приводило к нежелательному засорению пространства именования, поэтому новые имена доступны 
только в пределах класса ios. Если вам необходимо использовать старые имена в сочетании с новой 
библиотекой, можно воспользоваться следующими определениями: 
const int _good = ios::goodbit; 
const int _bad = ios::badbit; 
const int _file = ios::filebit; 
const int _eof = ios::eofbit; 
typedef ios::io_state state_value ; 
Разработчики библиотек должны заботится о том, чтобы не добавлять новых имен к глобальному 
пространству именования. Если элементы перечисления входят в общий интерфейс библиотеки, они 
всегда должны использоваться в классе с префиксами, например, как ios::goodbit и ios::io_state. 
Для переменной любого типа, для которого определены операции << и >>, цикл копирования 
записывается следующим образом: 
while (cin>>z) cout << z << '\n'; 
Если поток появляется в условии, то проверяется состояние потока, и условие выполняется (т.е. 
результат его не 0) только для состояния good(). Как раз в приведенном выше цикле проверяется 
состояние потока istream, что является результатом операции cin>>z. Чтобы узнать, почему произошла 
неудача в цикле или условии, надо проверить состояние. Такая проверка для потока реализуется с 


Бьерн Страуструп.
Язык программирования С++ 
 
265 
помощью операции приведения (7.3.2). 
Так, если z является символьным вектором, то в приведенном цикле читается стандартный ввод и 
выдается для каждой строки стандартного вывода по одному слову (т.е. последовательности символов, 
не являющихся обобщенными пробелами). Если z имеет тип complex, то в этом цикле с помощью 
операций, определенных в 10.2.2 и 10.2.3, будут копироваться комплексные числа. Шаблонную 
функцию копирования для потоков со значениями произвольного типа можно написать следующим 
образом: 
complex z; 
iocopy(z,cin,cout); // 
копирование complex 
double d; 
iocopy(d,cin,cout); // 
копирование double 
char c; 
iocopy(c,cin,cout); // 
копирование char 
Поскольку 
надоедает 
проверять 
на корректность каждую операцию ввода-вывода, то 
распространенным источником ошибок являются именно те места в программе, где такой контроль 
существенен. Обычно операции вывода не проверяют, но иногда они могут завершиться неудачно. 
Потоковый ввод-вывод разрабатывался из того принципа, чтобы сделать исключительные ситуации 
легкодоступными, и тем самым упростить обработку ошибок в процессе ввода-вывода. 


Достарыңызбен бөлісу:
1   ...   185   186   187   188   189   190   191   192   ...   256




©emirsaba.org 2024
әкімшілігінің қараңыз

    Басты бет