рефераты

рефераты

 
 
рефераты рефераты

Меню

Реферат: Turbo C++ Programer`s guide рефераты

Второй аргумент, ios::adjustfield, сообщает setf, какие биты должны быть установлены. Первый аргумент,ios::left, сообщает setf,в какие именно значения устанавливаютсяэти биты. Альтернативно можно использовать манипуляторы setfill, setiosflags иresetiosflags, которые позволяют модифицировать символ-заполнитель и направление дополненияпри форматировании (см. табл.3.1).

Вставки, определяемые пользователем

Вы можете писать собственныевставки для вывода своих собственных типов данных, перегружая для этого операцию<<. Предположим, у вас имеется тип

struct info (*

char *name;

double val;

char *units;

(*;

Вы можете перегрузить << следующим образом:

ostream& operator << (ostream& s, info& m)

(*

s << m.name << " " << m.val << " " << m.units;

*)

Операторы

info x;

...

// здесь инициализируется x

...

cout << x;

даст на выходе что-либо вроде "capacity 1.25 liters".

Ввод   ----------------------------------------------

Ввод потоком аналогичен выводу, но использует перегруженную операцию сдвига вправо, >>, и называется операцией извлечения, или извлечением. Операция >> обеспечивает более компактную и читаемую альтернативу семейству функций scanf в stdio (она также лучше защищена от ошибок). Левый операнд >> представляет собой объект типа класса istream. Как и для вывода, правый операнд может быть любого типа, для которого определен вывод потоком.

Все встроенные типы, перечисленные вышедля вывода, также имеют предопределенные операции извлечения. Операция >> может быть такжеперегружена для ввода потоком ваших собственных типов данных. Операция >>,перегруженная для типа type, называется извлечением type. Например,

cin >> x;

вводит значение из cin (стандартный поток ввода, обычно направляемый с клавиатуры) в x. Функции преобразования и форматирования зависят от типа x, от того, каким образом определено извлечение, а также от установок флагов состояния формата.

По умолчанию >> опускает пробельные символы (как определено функцией isspace в ctype.h), а затем считывает символы, соответствующие типуобъекта ввода. Пропуск пробельных символов управляется флагом ios::skipws в перечислимой переменной состояний формата (см. "Форматирование вывода" на стр.170 оригинала). Флаг skipws обычно устанавливает пропуск пробельных символов. Очистка этогофлага (например, припомощиsetf)выключает пропуск пробельных символов. Отметим также специальныйманипулятор "приемника", ws, который позволяет игнорировать пробельные символы (см. таблицу 3.1).

Изменение извлечений

Как и в случае <<, операция >> обладает свойством ассоциативности слева и возвращает левый операнд.  Левый операнд является ссылкой на объект istream, для которого была вызвана данная операция. Это позволяет объединятьв одном операторе несколько операций ввода. Рассмотрим следующий пример:

int i;

double d;

cin >> i >> d;

Последняя строка вызывает пропуск пробельных символов; цифры, считываемые со стандартного устройства ввода(по умолчаниюэто ваша клавиатура), преобразуются затем во внутренний двоичный формат и записываются в переменную i; затемснова пропускаются пробельные символы, и наконец считываетсячисло с плавающей точкой, преобразуется и записывается в переменную d.

Извлечения для встроенных типов

Извлечения для встроенных типов делятсяна три категории: интегральные,с плавающей точкой и строковые. Каждое из них описано ниже, в следующих разделах. Для всех числовых типов в случае, еслипервыйне-пробельный символ не является цифрой или знаком (или десятичной точкой для преобразований с плавающей точкой), поток вводит состояние ошибки (это описано на стр.177 оригинала) и вплоть до сброса состояния ошибки любой дальнейший ввод запрещен.

Интегральные извлечения

Для типов short, int и long (signed и unsigned) действие операции >> по умолчанию заключаетсяв пропуске не-пробельныхсимволов и преобразовании интегрального значения путем чтения символов ввода до тех пор, пока не встретится символ, который не может являться допустимой частью представления данного типа. Формат распознаваемых интегральных значений тот же, что и для целочисленных констант С++, заисключением целочисленных суффиксов. (См. стр.11 оригинала).

Предупреждение

Если вы задали преобразования типа hex, dec или oct, то именно такиерезультаты выи получите.  0x10 становится0 в десятичном или восьмеричном представлении; 010 становится 10 в десятичном представлении и 16 в шестнадцатиричном.

Извлечения с плавающей точкой

Для типов float и double действие операции >> состоит в пропуске пробельных символов и преобразовании значения с плавающей точкой путем чтения вводимых символов до тех пор, пока не встретится символ, который не может являться частью представлениячисла с плавающей точкой. Формат распознаваемых значений с плавающей точкой тот же, что и для констант с плавающей точкой С++, за исключением суффиксов. (См. стр.16 оригинала).

Символьные извлечения

Для типа char (signed или unsigned) действие операции >> состоит в пропускепробельных символов и записи следующего (не-пробельного) символа. Если вам требуетсяпрочесть следующий символ, неважно, является ли он пробельным или нет, то можно использовать одну из функций-компонентов get:

char ch;

cin.get(ch); // ch устанавливается на следующий символ потока // даже если это пробельный символ

Функции get для ввода играют ту же роль, что функции putдля вывода. Следующий вариант get позволяет управлять числом извлекаемых символов, их размещением и оконечным символом:

istream& istream::get(char *buf, int max, int term='\n');

Эта функция считывает символы из входного потока в символьный массив buf до тех пор, пока не будет считано max-1 символов, либо пока не встретится символ, заданный term, в зависимости от того, что произойдет раньше. Завершающийпустойсимволдобавляется автоматически. По умолчаниютерминатором (который не требуется задавать) является символ новой строки ('\n'). Сам терминатор в массив buf не считывается и из istream не удаляется. Массив buf должен иметь размер как минимум max символов.

По аналогии с функцией-компонентом ostream write (см. стр.170 оригинала) можно прочитать "сырые" двоичные данные следующим образом:

cin.read ( (char*)&x, sizeof(x) );

Для типа char* (рассматриваемого как строка) действие операции >> состоит в пропуске пробельныхсимволов и записи следующих (не-пробельных) символов до тех пор, пока не встретится следующий пробельный символ. Затем добавляется завершающий нулевой (0) символ.Следует предъявлятьосторожность и избегать "переполнения" строки. Ширина по умолчанию, равная нулю (означает, что предельное значение не задано), может быть изменена при помощи setw следующим образом:

char array[SIZE];

...

// инициализация массива

...

cin.width(sizrof(array));

cin >> array                        // позволяет избежать переполнения

В случае любого вводавстроенных типов, если конец ввода встретится ранее первого не-пробельного символа, вмишеньbuf ничего записано не будет, а состояние istream будет установлено равным "отказу". Таким образом, если мишень была не инициализирована, то она и останется не инициализированной.

Функция возвращения

Функция-компонент

istream istream::putback(char c);

возвратит обратно в istream один символ c; если этот символ не может быть помещен обратно, то устанавливается состояние потока "отказ". Следующая простая подпрограмма выполняет считывание идентификатора С++ со стандартного устройства ввода:

void getident (char *s /* сюда помещается идентификатор */ )

(*

char c = 0;   // защита от конца файла

cin >> c;   // пропуск пробельных символов

if (isalpha(c) \!\! c == '_')

do (*

*s++ = c;

c = 0;   // защита от конца файла

cin.get(c);

*) while (isalnum(c) \!\! c =='_');

*s = 0;   // терминатор строки

if (c)

cin.putback(c);  // один символ всегда лишний

*)

Ввод типов, определяемых пользователем

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

istream& operator >> (istream& s, info& m);

(*

s >> m.name >> m.val >> m.units;

return s;

*)

(В реальных прикладных программах, разумеется, вы можете добавить коды для проверки ошибок ввода).  Для считывания строки ввода, такойкак "capacity 1.25 liters", можно использовать следующую запись:

cin >> m;

Инициализация потоков

Потоки cin, cout, cerr и clog инициализируются и открываются при загрузке программы и затем подключаются к соответствующим стандартным файлам. Инициализация (конструирование) потока означает ассоциирование его с буфером потока. Класс ostream имеет следующий конструктор:

ostream::ostream(streambuf*);

который инициализирует переменные состояния ios и ассоциирует буфер потока с объектом ostream. Конструктор istream работает аналогичным образом. В большинстве случаев вам не требуется специально рассматривать вопросами буферизации.

Библиотека iostream предлагает множество классов, производных от streambuf, ostream и istream, что дает широкий выбор методов создания потоков с различными источниками и приемниками, а также различными методами буферизации.

Следующие классы являются производными от класса streambuf:

filebuffilebuf поддерживает ввод/вывод через дескрипторы файлов. Функции-компонент класса поддерживают функции открытия, закрытия файлов и поиска.

stdiobufstdiobuf поддерживает ввод/вывод через структуры stdio FILE и предназначается исключительно для совместимости кодов С++ при их комбинировании с существующими программами С.

strstreambufstrstreambuf позволяет ввод и вывод символов из байтовых массивов в памяти. Два дополнительных класса, istrstream и ostrstream, обеспечивают ввод/ вывод с форматированием в памяти.

Специализированные классы для ввода/вывода в файл являются производными:

ifstream  является производным от istream

ofstream  является производным от ostream

fstream  является производным от iostream

Эти триклассаподдерживают форматированный ввод/вывод в файлы при помощи буферов файлов (filebuf).

Простой ввод/вывод в файл

Класс ofstream наследует операции вставки отostream, а ifstream наследует операцииизвлечения отistream. Они также обеспечивают конструкторы и функции-компоненты для создании файлов и обработки ввода/вывода в этот файл. Следуетвключать fstream.h во все программы, где используются эти файлы. Рассмотрим следующий пример, в котором файл FILE_FROM копируется в FILE_TO:

#include fstream.h

...

char ch;

ifstream f1("file_from");

if (!f1) errmsg("Cannot open 'filr_from' for input");

ofstream f2("file_to");

if (!f2) errmsg("Cannot open 'filr_to' for output");

while ( f2 && f1.get(ch) ) f2.put(ch);

Ошибки, связанные с потоками, подробно обсуждаются на стр.181 оригинала.

Отметим, что если конструкторы ifstream или ofstream не могут открыть указанные файлы, то устанавливается соответствующее состояние ошибки потока.

Конструкторы позволяют объявить потокфайла без задания именованного файла. Затем вы можете ассоциировать данный поток файла с конкретным файлом:

ofstream ofile;                         // создание выходного потока файла

...

ofile.open("payroll");   // поток ofile ассоциируется с

// файлом payroll

// работа с некоторым паролем

ofile.close();                          // payroll закрывается

ofile.open("employee"); // поток ofile можно использовать // повторно

По умолчанию файлы открываются в текстовом режиме.Это означает, что на вводе последовательность возврата каретки/перевода строки преобразуется в символ '\n'. На выводе символ '\n' преобразуется в последовательность возврат каретки/перевод строки. В двоичном режиме такие преобразования не выполняются.

Функциякомпонента ofstream::open объявляется следующим образом:

void open(char * name, int=ios::out, int prot=filуbuf:: openprot);

Аналогично, объявление ifstream::open имеет вид:

void open(char                      *             name,               int=ios::in,                        int

prot=filуbuf::openprot);

Второй аргумент, называемыйрежимом открытия, имеет показанные умолчания. Аргумент режима открытия (возможно, связанный операцией ИЛИ с несколькими битами режима)можно явно задать в следующей форме:

Бит режимаДействие

ios::appДобавление данных - запись всегда в конец файла ios::ateПоиск конца файла после первоначального открытия

ios::inОткрытие на ввод (подразумевается для ifstream) ios::outОткрытие на вывод (подразумевается для ofstream)

ios::truncУничтожение содержимого в случае, если файл существует (подразумевается, если ios::out задано, и ни ios::ate, ни ios::app не заданы)

ios::nocreateЕсли файл не существует, то open дает ошибку

ios::noreplace Если файл существует, open для файлов вывода дает ошибку, если не установлены ate или app

-----------------------------------------------------------

Мнемоника режима берется из перечислимого значения open _mode в ios:

class ios (*

public:

enum open_mode (* in, out, app, ate, nocreate, noreplace *);

*);

Оператор

ofstream ofile("data",ios::app\!ios::nocreate);

попытается открыть файл DATA на вывод в режиме append; если файл не существует, это приведет к неудаче. Информация об этой неудаче будет обозначена состоянием ошибки ofile. В случае удачного завершения поток ofile будет добавлен к файлу DATA. Класс fstream (производный от двух классов ifstream и ofsrtream) может использоваться для создания файлов, одновременно позволяющих и ввод, и вывод:

fstream inout("data:,ios::in\!ios::out);

inout << i;

...

inout >> j;

Для определения текущей позиции "get" или текущей позиции "put" файла можно воспользоваться функциями tellg и tellp; они определяют положение в потоке, гдебудет выполнена следующая операция вывода или ввода:

streampos cgp = inout.tellg(); // cgp - это текущая позиция get

где streampos это typedef в fstream.h. Функции-компоненты seekg и seekp могут сбрасывать значения текущей позиции get и put:

inout.seekg(cp); // установка в cp текущей позиции "put"

Варианты seekp и seekg позволяют получить искомые позиции в относительных смещениях:

inout.seekg(5,ios::beg); // перемещение cp на 5 байт от начала

inout.seekg(5,ios::cur); // перемещение cp на 5 байт вперед

inout.seekp(5,ios::end); // перемещение cp на 5 байт до конца

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

Состояния ошибки потока ввода/вывода

Каждый поток имеет связанное с ним состояние ошибки, т. е. набор битов ошибок, объявленный как перечислимое значение io_state в классе ios:

class ios (*

public:

...

// биты состояния потока

enum io_state (*

goodbit            =   0x00,

eofbit               =   0x01,

failbit               =   0x02,

badbit              =   0x04,

hardfail            =   0x10

*);

...

*);

Отметим,что goodbit в действительности не является витом, а представляет собой нулевое значение, указывающее на то,что никакие биты ошибки не устанавливались.

Ошибки ввода/вывода потоком устанавливает соответствующий бит(ы), как указано в табл.3.2.

Биты ошибок ios                        Таблица 3.2

Бит состояния Его смысл

goodbit Если этот бит не установлен, то все в порядке.

eofbit  "Конец файла": устанавливается, если istream не

имеет больше битов для извлечения. Последующие

попытки выполнить извлечение игнорируются.

failbit Устанавливается, если последняя операции ввода/

вывода (извлечение или преобразование) окончилась

неудачей. После сброса данного бита ошибки поток

готов к последующему использованию.

badbit  Устанавливается, если последняя попытка ввода/

вывода являлась недопустимой. Поток может быть использован (не всегда) после сброса условия ошибки.

hardfail Устанавливается, если для данного потока встретилось невосстановимое состояние ошибки.

-----------------------------------------------------------

После того, как поток получил состояние ошибки, все попытки вставки или извлечения из данного потока будут игнорироваться до тех пор, пока не будет исправлено условие, вызвавшее состояние ошибки, а бит(ы) ошибки очищен(ы) (при помощи, например, функции компонента ios::clear(i). Функциякомпонент ios::clear(i) фактически устанавливает биты ошибки в соответствии с целочисленным аргументом i, так что ios::clear(0) очищает все биты ошибки, за исключением hardfail, который таким образом очищен быть не может.

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

Функции-компоненты для обработки текущего состояния потокаТаблица 3.3

Функция компонент               Действие

int rdstate();                                 Возвращает текущее состояние ошибки

void clear(int i=0); Устанавливает биты ошибки в i. Например, код str.clear(ios::failbit\!str.rdstate());

устанавливает failbit потока str без разрушения прочих битов

int good();                          Возвращает не-нулевое значение, если биты

ошибки не устанавливались; в противном случае

Страницы: 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