Анимация
JavaScript


Главная  Библионтека 

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 [ 185 ] 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239

если перед операцрхей поток данных был приведен в состояние goodbit. В при-тивном случае может оказаться, что флаги были установлены одной из предтне-ствующих операций.

функции для работы с состоянием потока данных

в табл. 13.4 перечислены функции для работы с текущим состоянием потока данных.

Таблица 13.4. Функции для работы с состоянием потока данных Функция Описание

good() Возвращает true, если поток данных находится в нормальном состоянии

(то есть при установке флага goodbit)

eof() Возвращает tme при обнаружении признака конца фата (установка флага eofbit)

fail() Возвращает true при обнаружении ошибки (установка флага fallbit или badbit)

bad() Возвращает true при обнаружении фатальной ошибки (установка флага badbit)

rdstateO Возвращает установленные флаги

с1еаг() Сбрасывает все флаги

clear(state) Сбрасывает все флаги и устанавливает флаги, содержащиеся в state setstate(state) Устанавливает флаги, содержащиеся в state

Первые четыре функции проверяют состояние отдельных флагов и возвращают логическую 1*еличину. Учтите, что функция fail() возвращает true при установке как failbit, так и badbit. Хотя такое поведение объясняется в основном историческими причинами, у него есть определенные достоинства - для выявления ошибки достаточно проверить всего одно условие.

Также существуют более общие функции для проверки и изменения состояния флагов. При вызове функции с1еаг() без параметров сбрасываются все флаги ошибок (в том числе и eofbit):

Сброс всех флагов ошибок (включая eofbit) strm.clearO;

Если функция с1еаг() вызывается с передачей параметра, то состояние потока данных изменяется в соответствии с переданным значением; переданные флаги устанавливаются для потока данных, а остальные флаги сбрасываются. У этого правила есть единственное исключение: при отсутствии потокови1"о буфера (когда rdbuf()==0) флаг badbit устанавливается всегда; за подробностями обращайтесь к с. 613.

Следующий пример показывает, как установить и сбросить флаг failbit:

Проверка установки флага failbit

if (strm.rdstateO & std::ios::failbit) {

std;:cout « failbit was set" « std::endl:



Сброс только флага failbit

strm.clear (strm.rdstateO & -std::1os::failb1t):

В этом примере используются поразрядные операторы & и Оператор возвращает поразрядное дополнение своего аргумента. Следовательно, показанное ниже выражение возвращает временное значение, в котором установлены все биты, кроме failbit:

-ios::fa1lbit

Оператор & возвращает результат поразрядного объединения своих операндов. В результате операции устанавливаются только биты, установленные в обоих операндах. При поразрядном объединении всех текущих установленных флагов (rdstateO) со всеми установленными битами, кроме failbit, бит failbit сбрасывается, а значения всех остальных битов сохраняются.

Потоки данных можно настроить так, чтобы при установке флагов функциями с1еаг() и setstateO генерировались исключения (см. с. 576).

Также следует помнить о необходимости явного сброса битов ошибок. Язык С позволял продолжить чтение символов после ошибки форматирования. Например, если функции scanf() не удавалось прочитать целое число, программа могла ввести оставшиеся символы. Таким образом, операция чтения завершалась неудачей, но входной поток данных оставался в нормальном состоянии. В С++ дело обстоит иначе. При установке бита failbit все последующие операции с потоком данных игнорируются до тех пор, пока флаг failbit не будет сброшен программой.

Вообще говоря, установленные флаги всего лишь отражают события, которые происходили в прошлом. Наличие установленного флага после какой-либо операции не всегда означает, что именно эта операция привела к его установке. Флаг также мог быть установлен еще до выполнения этой операции. Следовательно, если вы собираетесь проверять результат выполнения операции по состоянию флагов, перед ее выполнением следует привести поток данных к состоянию goodbit (если нет полной уверенности в том, что он уже находится в этом состоянии). Кроме того, после сброса флагов операция может верпуть другой результат. Например, даже если флаг eofbit в результате операции был установлен, это еще пе означает, что после сброса eofbit (и всех остальных установленных битов) флаг будет снова установлен при повторном выполнении операции, поскольку между вызовами файл может увеличиться.

Состояние потока данных и логические условия

в табл. 13.5 приведены две операторные функции, предназначенные для проверки состояния потоков данных в логических выражениях.

Таблица 13.5. Потоковые операторы для логических выражений Функция Описание

operator void*() Проверяет нормальное состояние потока данных (эквивалент !fall()) operator! () Проверяет ошибочное состояние потока данных (эквивалент fail())



Оператор void*() обеспечивает короткую и наглядную запись проверки состояния потока данных в управляющих структурах:

Пока стандартный поток ввода находится в нормальном состоянии... while (std::cin) {

Проверка логических условий в управляющих структурах не требует прямого преобразования к bool. Достаточно уникального преобразования к целому типу (например, int или char) или к тину указателя. Для чтения объекта и проверки результата в одной команде часто требуется преобразование к void*:

if (std: :Cin » x) {

Чтение X выполнено успешно

Как было показано ранее, следующее выражение возвращает cin: std::cin » х

Следовательно, после чтения х команда эквивалентна такой команде: if (std::cin) {

Объект cin часто используется при проверке условий; оператор void* этого объекта возвращает признак наличия ошибки потока данных.

Этот прием обычно применяется в циклах, выполняющих чтение и обработку объектов:

Пока удается прочитать obj while (std::cin » obj) {

Обработка obj (в данном случае - npocToti вывод)

std::cout « obj « std::endl:

В этом фрагменте легко угадывается классический синтаксис фильтров С, примененный к объектам С++. Цикл завершается при установке флага failbit или badbit Эти флаги устанавливаются при возникновении ошибки или достижении конца файла (попытка чтения за концом файла приводит к установке флага eofbit или badbit, как показано на с. 572). По умолчанию оператор >> игнорирует начальные пропуски. Обычно это вполне устраивает программиста, но если obj относится к типу char, то пропуски могут оказаться существенными. В этом случае в реализации фильтра можно использовать функции get() и put() потоковых классов (см. с. 582), а еще лучше - итератор istreambufjterator (см. с. 640).

Оператор I проверяет обратное условие. В соответствии со своим определением он возвращает true, если для потока данных установлен бит failbit или badbit. Возможный вариант использования;



0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 [ 185 ] 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239