|
Программирование >> Поддержка объектно-ориентированного программирования
ostream). Различие между состояниями, задаваемыми как fail() или как bad() уловить трудно, и оно имеет смысл только для разработчиков операций ввода. Если состояние есть fail(), то считается, что поток не поврежден, и никакие символы не пропали; о состоянии bad() ничего сказать нельзя. Значения, обозначающие эти состояния, определены в классе ios: class ios { ... public: enum io state { goodbit=0, eofbit=1, filebit=2, badbit=4, ... Истинные значения состояний зависят от реализации, и указанные значения приведены только, чтобы избежать синтаксически неправильных конструкций. Проверять состояние потока можно следующим образом: switch (cin.rdstateO) { 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. Чтобы узнать, почему произошла неудача в цикле или условии, надо проверить состояние. Такая проверка для потока реализуется с помощью операции приведения (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 Поскольку надоедает проверять на корректность каждую операцию ввода-вывода, то распространенным источником ошибок являются именно те места в программе, где такой контроль существенен. Обычно операции вывода не проверяют, но иногда они могут завершиться неудачно. Потоковый ввод-вывод разрабатывался из того принципа, чтобы сделать исключительные ситуации легкодоступными, и тем самым упростить обработку ошибок в процессе ввода-вывода. 10.3.3 Ввод пользовательских типов Операцию ввода для пользовательского типа можно определить в точности так же, как и операцию вывода, но для операции ввода существенно, чтобы второй параметр имел тип ссылки, например: istream& operator>>(istream& s, complex& a) формат input рассчитан на 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(ios::badbit); установим состояние else { s.putback(c); s >> re; if (s) a = complex(re,im); return s; Несмотря на сжатость кода, обрабатывающего ошибки, на самом деле учитывается большая часть ошибок. Инициализация локальной переменной с нужна для того, чтобы в нее не попало случайное значение, например (, в случае неудачной операции. Последняя проверка состояния потока гарантирует, что параметр a получит значение только при успешном вводе. Операция, устанавливающая состояние потока, названа clear() (здесь clear - ясный, правильный), поскольку чаще всего она используется для восстановления состояния потока как good(); значением по умолчанию для параметра ios::clear() является ios::goodbit. 10.4 Форматирование Все примеры из 1 0.2 содержали неформатированный вывод, который являлся преобразованием объекта в последовательность символов, задаваемую стандартными правилами, длина которой также определяется этими правилами. Часто программистам требуются более развитые возможности. Так, возникает потребность контролировать размер памяти, необходимой для операции вывода, и формат, используемый для выдачи чисел. Точно так же допустимо управление некоторыми аспектами ввода. 10.4.1 Класс ios Большинство средств управления вводом-выводом сосредоточены в классе ios, который является базовым для ostream и istream. По сути здесь находится управление связью между istream или ostream и буфером, используемым для операций ввода-вывода. Именно класс ios контролирует: как символы попадают в буфер и как они выбираются оттуда. Так, в классе ios есть член, содержащий информацию об используемой при чтении или записи целых чисел системы счисления (десятичная, восьмеричная или шестнадцатеричная), о точности вещественных чисел и т.п., а также функции для проверки и установки значений переменных, управляющих потоком. class ios { ... public: ostream* tie(ostream* s); связать input и output ostream* tie(); возвратить tie int width(int w); установить поле width int width() const; char fill(char); установить символ заполнения char fill() const; вернуть символ заполнения long flags(long f); long flags() const; long setf(long setbits, long field); long setf(long); long unsetf(long); int precision(int); установить точность для float int precision() const; int rdstate(); const; состояния потоков, см. $$10.3.2 int eof() const; int fail() const; int bad() const; int good() const; void clear(int i=0); ... В 1 0.3.2 описаны функции, работающие с состоянием потока, остальные приведены ниже. 10.4.1.1 Связывание потоков Функция tie() может установить и разорвать связь между ostream и istream. Рассмотрим пример: main() String s; cout << Password: ; cin >> s; ... Как можно гарантировать, что приглашение Password: появится на экране прежде, чем выполниться операция чтения? Вывод в cout и ввод из cin буферизуются, причем независимо, поэтому Password: появится только по завершении программы, когда закроется буфер вывода.
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |