Ввод Типов, Определяемых Пользователем
Ввод для пользовательского типа может определяться точно так же, как вывод, за тем исключением, что для операции ввода важно, чтобы второй параметр был ссылочного типа. Например:
istream& operator>>(istream& s, complex& a) /* форматы ввода для complex; "f" обозначает float: f ( f ) ( f , f ) */ { double re = 0, im = 0; char c = 0; s >> c; if (c == "(") { s >> re >> c; if (c == ",") s >> im >> c; if (c != ")") s.clear(_bad); // установить state } else { s.putback(c); s >> re; } if (s) a = complex(re,im); return s; }
Несмотря на то, что не хватает кода обработки ошибок, большую часть видов ошибок это на самом деле обрабатывать будет. Локальная переменная c инициализируется, чтобы ее значение не оказалось случайно "(" после того, как операция окончится неудачно. Завершающая проверка состояния потока гарантирует, что значение параметра a будет изменяться только в том случае, если все идет хорошо. Операция установки состояния названа clear() (очистить), потому что она чаще всего используется для установки состояния потока заново как _good.
_good является значением параметра по умолчанию и для istream::clear(), и для ostream::clear().
Над операциями ввода надо поработать еще. Было бы, в частности, замечательно, если бы можно было задавать ввод в терминах шаблона (как в языках Снобол и Икон), а потом проверять, прошла ли успешна вся операция ввода. Такие операции должны были бы, конечно, обеспечивать некоторую дополнительную буферизацию, чтобы они могли восстанавливать поток ввода в его исходное состояние после неудачной попытки распознавания.
1 2 3 4
8 8 8
| |