Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Бьерн Страуструп C++.doc
Скачиваний:
12
Добавлен:
07.11.2018
Размер:
2.45 Mб
Скачать

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 Форматирование

Все примеры из 10.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);

//...

};

В 10.3.2 описаны функции, работающие с состоянием потока, остальные приведены ниже.