Анимация
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

sum = 0:

while (strm » value) { sum += value:

catch (...) {

/* Если исключение произошло не из-за достижения конца файла.

* - восстановить старую маску исключений

* - перезапустить исключение */

1f (Istrm.eofO) {

strm.exceptions(oldExceptions): Восстановление маски throw: Перезапуск исключения

Восстановление старой маски исключений strm.exceptions (oldExceptions):

Возврат суммы return sum:

Сначала функция сохраняет состояние маски исключений в переменной OldExceptions, чтобы восстановить ее позднее. Затем поток данных настраивается на выдачу исключений при требуемых условиях. Функция читает значения в цикле и суммирует их до тех пор, пока поток данных остается в нормальном состоянии. При достижении конца файла состояние потока данных перестает быть нормальным, и он генерирует исключение (хотя для флага eofbit исключение не генерировалось). Дело в том, что конец файла обнаруживается при неудачной тюнытке чтения новых данных, которая также устанавливает флаг failbit. Чтобы избежать выдачи исключения при достижении конца файла, мы организуем локальный перехват исключения и проверяем состояние потока данных функцией eof(). Исключение передается дальше только в том случае, если eof() возвращает false.

Следует помнить, что восстановление исходной маски исключений также может привести к выдаче исключений. Функция exceptions() генерирует исключение в том случае, если соответствующий флаг уже установлен для потока данных. Поэтому если поток данных генерировал исключения для флага eofbit, failbit или badbit при входе в функцию, эти исключения также будут переданы вызывающей стороне.

Ниже приведен простой пример вызова этой функции из main().

io/summaln.cpp #lnclude <1ostream> #include <cstdl1b>

namespace MyLib {

double readAndProcessSum (std;:istream&):



int mainO {

using namespace std; double sum;

try {

sum = MyLib:;readAndProcessSum(cin);

catch (const ios::failureSt error) {

cerr « "I/O exception: " « error.what() « endl: return EXITJAILURE:

catch (const exceptional error) {

cerr « "standard exception: " « error.whatO « endl: return EXITJAILURE;

catch (...) {

cerr « "unknown exception" « endl: return EXIT FAILURE;

Вывод суммы

cout « "sum: " « sum « endl;

Ho возникает вопрос: насколько оправданны эти хлопоты? Проще работать с потоками данных, которые не выдают исключений. В этом случае программа сама генерирует исключение при обнаружении ошибки. Дополнительным достоинством такого решения является возможность работы с пользовательскими сообщениями об ошибках и классами ошибок:

io/sum2a.cpp #include <istream>

namespace MyLib {

double readAndProcessSum (std::istream& strm)

double value, sum;

/* Пока поток остается в нормальном состоянии * - прочитать очередное значение и прибавить его к сумме */

sum = 0;

whi1е (strm » value) { sum += value;

if Clstrm.eofO) { throw std::ios:;failure

("input error in readAndProcessSumO");



Возврат суммы return sum;

Выглядит гораздо проще, не правда ли? Этой версии функции нужен заголовок <string>, поскольку конструктор класса failure получает в аргументе ссылку на константный объект string. Для конструирования объекта этого типа потребуется определение, а для передачи объявления достаточно заголовка <istream>.

итандартные функции ввода-вывода

Вместо стандартных операторов >> и << для чтения из потока данных и записи в поток данных можно использовать ряд других функций, представленных в этом разделе.

Эти функции предназначены для чтения и записи «неформатированных» данных (в отличие от операторов << и >>, которые читают и записывают «форматированные» данные). Функции при чтении никогда не игнорируют начальные пропуски (в отличие от операторов, которые по умолчанию начальные пропуски игнорируют). Кроме того, в них используется другой принцип обработки исключений: флаг badbit устанавливается, если функция генерирует исключение, причем не важно, кто является источником исключения - сама вызванная функция или исключение генерируется в результате установки флага состояния (см. с. 576). Если в маске исключений установлен флаг badbit, исключение передается дальше. Тем не менее функции неформатированного вывода, как и функции форматированного вывода, создают объект sentry (см. с. 631).

Для передачи ко;шчества символов в этих функциях используется тип streamsize:

namespace std {

typedef ... streamsize;

Тип streamsize обычно представляет собой знаковую версию size t. Тип является знаковым, потому что он также используется для передачи отрицательных значений.

Функции ввода

в следующих определениях istream обозначает потоковый класс, используемый для чтения. Это может быть класс istream, wistream или любая другая специализация класса шаблона basicjstream. Параметр char обозначает соответствующий тип символов (char для istream, wchar t для wistream). Другие типы и значения, выводимые курсивом, зависят от определения типа символов или класса трактовок, связанного с потоком данных.



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