46019 (665326), страница 26

Файл №665326 46019 (Turbo C++ Programer`s guide) 26 страница46019 (665326) страница 262016-07-31СтудИзба
Просмтор этого файла доступен только зарегистрированным пользователям. Но у нас супер быстрая регистрация: достаточно только электронной почты!

Текст из файла (страница 26)

va_arg (stdarg.h)

va_end (stdarg.h)

va_stsrt (stdarg.h)

Глава 3 Потоки С++

Данная глава содержит краткий обзор ввода/вывода потоков С++. Ввод/вывод потоков в С++используется для преобразования типизированных объектов в читаемый текст, и обратно. Он позволяет определять функции ввода/вывода, которые затем автоматически используются применительно к соответствующим определенных пользователем типам. Последующие примеры находятся в Главе 5, "Основы С++" документа "Начало работы"; приводимая там же библиография предлагает несколько названий книг для углубленного изучения данного примера.

Новые потоки вместо старых

Turbo C++ поддерживает как старую библиотеку С++ stream, так и новую усовершенствованную библиотеку iostream С++ версии 2.0. Возможность работы с обеими версиями поможет вам, если у вас имеются программы, написанные по старым соглашениям, и вы желаете использовать Turbo C++ для перехода к более эффективным потокам ввода/вывода версии2.0. Мы настоятельно рекомендуем вампри создании новых программ пользоваться библиотекой iostream версии 2.0. Приводя некоторые материалы, необходимые дляперехода к потокам версии 2.0 (начиная со стр.184 оригинала), данная глава главным образом посвящается классам иправилам потоков iostream версии 2.0.

Использование потоков 2.0

Усовершенствованные потоки iostream версии 2.0, хотя и обеспечивают по большей части совместимость для старой версии С++, предлагают тем не менее новые возможности, связанные с использованием множественного наследования и прочими средствами, появившимися в С++ версии 2.0.

Обсуждение различий между старыми потоками и новыми потоками, а также основы преобразования старых потоков в новые см. в разделах "Использование старых потоков" и "Основы перехода к потокам версии 2.0" в конце настоящей главы.

Концепция потоков С++ нацелена на решение нескольких проблем, решаемых стандартными библиотечнымифункциями ввода/ вывода С, такими какprintfи scanf. Последние, разумеется остаются доступными для программиста, работающего в С++, но улучшенная гибкость и элегантность потоков С++ уменьшают привлекательность функций библиотеки stdio.h. Классы, связанные с потоками С++, предлагают вам расширяемые библиотеки, позволяющие вам выполнять форматированный ввод/выводс контролемтипов какдля предопределенных, так и для определяемых пользователем типов данных спомощью перегруженных операцийи прочих объектно-ориентированных методов.

Для обращения к вводу/выводу потоком ваша программа должна включать файл iostream.h. Для некоторых функций потоков требуются и другие файлы заголовка. Например, для выполнения форматирования в оперативной памяти с использованием классов istrstream и ostrstream необходим файл strstream.h. Файл заголовка strstream.h включает также iostream.h. Если вам требуется класс fstream, включите файл fstream.h,такжевключающий iostream.h. И разумеется, можно включить одновременно и fstream.h, и strstream.h.

Что такое поток?

Потоком называется абстрактное понятие, относящееся к любому переносу данных от источника (или поставщика данных) к приемнику (или потребителю) данных. Также используются синонимы извлечение, прием и получение, когда речь идет о вводе символов от источника, и вставка, помещение или запоминание, когда речь идет о выводе символов на приемник.

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

Библиотека iostream

Библиотека iostream имеет два параллельных класса: streambuf и ios. Оба они являются классами низкого уровня и каждый выполняет свой круг задач.

streambuf

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

ios

Класс ios (и следовательно, производные от него классы) содержит указатель на streambuf.

ios имеет два производных класса: istream (для ввода) и ostream (для вывода). Другой класс, iostream, является производным классом сразуот istream иostream вследствие множественного наследования:

class ios;

class istream : virtual public ios;

class ostream : virtual public ios;

classiostream : public istream, public ostream;

Кроме того, существуеттри класса withassign, являющихся производными классами от istream, ostream и iostream:

class istream_withassign : public istream;

class ostream_withassign : public ostream;

class iostream_withassign : public iostream;

Классы потоков

- Класс ios содержит переменные состояния для интерфейса с streambuf и обработки ошибок.

- Класс istream поддерживает как форматированные, так и неформатированные преобразования потоков символов, извлекаемых из streambuf.

- Класс ostream поддерживает как форматированные, так и неформатированные преобразования потоков символов, помещаемых в streambuf.

- Класс iostream объединяет классы istream и ostream для двунаправленных операций, в которых один поток действует и как источник, и как приемник.

- Производные классы withassign обеспечивают четыре предопределенных "стандартных" потока: cin, cout, cerr и clog, описываемые в следующем разделе. Классы withassign добавляют к соответствующим базовым классам операции присвоения, следующим образом:

class istream_withassign : public istream (*

istream_withassign();

istream& operator=(istream&);

istream& operator=(streambuf*);

*)

и аналогично для ostream_withassign и

iostream_withassign.

Классом потока называется любой класс, производный от классов istream и ostream.

Четыре стандартных потока

Программы С++ начинаются с четырьмя предопределенными открытыми потоками, объявленными как объекты классов withassign в iostream.h следующим образом:

extern istream_withassign cin;

extern ostream_withassign cout;

extern ostream_withassign cerr;

extern ostream_withassign clog;

Их конструкторывызываются всякий раз при включении iostream.h, но фактическая инициализация выполняется только один раз.

Четыре стандартных потока выполняют следующее:

cin Стандартный ввод (дескриптор файла 0)

(Соответствует stdin)

cout Стандартный вывод (дескриптор файла 1) (Соответствует stdout)

cerr Стандартный вывод ошибок (дескриптор файла 2). cerr буферизуется поблочно; очистка буфера происходит при каждой новой вставке

(Соответствует stderr)

clog Данный поток представляет собой полностью буферизуемую версию cerr.

Как и в С, вы можете переназначить эти стандартные имена на другие файлы или символьные буферы после загрузки программы.

Вывод

Вывод потока осуществляетсяоператором вставки,или помещения, <<. Для операций вывода перегружаетсястандартная операция сдвига влево <<. Ее левый операнд представляет собой объект типа класса ostream. Правый операнд может иметь любой тип, для которого определен вывод потоком (подробнее об этом говорится ниже). Вывод потоком определен для встроенных типов. Операция<<, перегруженнаядля типа type, называется вставкойэтого типа. Например,

cout << "Hello!\n";

записывает строку "Hello!" в cout (стандартный поток вывода, который обычно направлен на экран), после чего следует новая строка. Здесь << - это строка вставки типа char*.

Операция << обладает ассоциативностью слева и возвращает ссылку на объект ostream, для которого она вызывалась.Это позволяет организовать каскадные вставки:

void function_display(int i, double d)

(*

cout << "i=" << i << ", d=" << d << "\n";

*)

Это вызовет вывод чего-либо вроде:

i = 8, d = 2.34

на стандартное устройство вывода.

Отметим, что перегрузка не изменяет нормального приоритета выполнения операции <<, поэтому можно записать:

cout << "sum = " << x+y << "\n";

без круглых скобок. Однако, в случае

cout << (x&y) << "\n";

круглые скобки нужны.

Встроенные типы

Типы вставок, поддерживаемые непосредственно,это : char (signed и unsigned), short (signed иunsigned), int (signed и unsigned), long (signed и unsigned), char* (рассматриваемый как строка), float, double, long double и void*. Интегральные типы преобразовываются по правилам, по умолчанию действующим для printf (еслиэти правила не изменены путем установки различных флагов ios).Например, если заданы объявления int i; long l;, то следующие два оператора

cout << i << " " << l;

printf("%d %ld, i, l);

приведут к одному и тому же результату.

Аналогичным образом, типы сплавающей точкой преобразовываются правилам умолчания для printf с преобразованием %g. Итак, в случае объявления double d;, операторы

cout << d;

printf("%g", d);

дают один и тот же результат.

Вставка указателя (void*) также предопределена:

int i = 1;

cout << &i; // указатель выводится на дисплей в шестнадцати// ричном формате

Вставка char работает следующим образом:

char ch = 'A';

cout << ch; // на дисплей выводится А

Функции put и write

Для вывода двоичных данных или отдельного символа можно использовать функцию-компонент put, объявленнуюв ostream следующим образом:

ostream ostream::put (char ch);

При объявлении int ch='x'; следующие две строки эквивалентны:

cout.put(ch);

cout << (char)ch;

Функция-компонент writeпозволяет вывод больших по размеру объектов:

ostream& ostream::write(const signed char* ptr, int n);

ostream& ostream::write(const unsigned char* ptr, int n);

Функции write выводят nсимволов (включая любые входящие пустые символы) в двоичномформате. В отличие от строковой вставки, write не прекращает работу, встретив пустой символ. Например,

cout.write((char *)&x, sizeof(x))

пошлет непреобразованное представление х настандартное устройство вывода.

Существует тонкое различие между форматированной операцией << и неформатированнымифункциями putи write. Форматированная операция может вызвать очистку связанных потоков и иметь атрибут ширины поля.Неформатированные операции не обладают этими свойствами. Поэтому cout << 'a' и cout put ('a') могут давать разные результаты. Все флаги форматирования применимы к <<, но ни один из них не применим к put или write.

Форматирование вывода

Форматирование ввода и вывода определяется различными флагами состояний формата, перечисленными в классе ios. Эти состояния определяются битами числа типа long int следующим образом:

public:

enum (*

skipws = 0x0001, // пропуск пробельного символа на вводе

left = 0x0002, // вывод с левым выравниванием

right = 0x0004, // вывод с правым выравниванием

internal = 0x0008, // заполнитель после знака или

// указателя системы счисления

dec = 0x0010, // десятичное преобразование

oct = 0x0020, // восьмеричное преобразование

hex = 0x0040, // шестнадцатиричное преобразование

showbase = 0x0080, // показать на выходе указатель

// системы счисления

showpoint = 0x0100, // показать позицию десятичной точки

// (на выходе)

uppercase = 0x0200, // вывод шестнадцатиричных значений

// буквами верхнего регистра

showpos = 0x0400, // показать знак "+" для положительных

// чисел

scientific = 0x0800, // использовать запись чисел с плава-

// ющей точкой с выводом экспоненты Е

// например, 12345E2

fixed = 0x1000, // использовать запись чисел с плава-

// ющей точкой типа 123.45

unitbuf = 0x2000, // стирание всех потоков после вставки

stdio = 0x4000, // стирание stdout и stderr после

// вставки

*);

Разумеется, этифлаги наследуются производными классами ostream и istream. Приотсутствии специальных действий пользователяфлагиустанавливаются таким образом, чтобы выполнялось показанное впримерах выше форматирование по умолчанию. Существуют функции, позволяющие установке,проверку и сбросфлаговформата, как по отдельности, так и связанными группами. Некоторые флаги автоматически очищаются после каждого ввода/ вывода.

Основание системы счисления при преобразованиях

По умолчанию вставкаинтегральных типов выполняется в десятичной записи. Это можно изменить соответствующими установками флагов ios::dec, ios::oct и ios::hex (см. раздел "манипуляторы"). Есливсе эти флаги равнынулю (по умолчанию), то вставка выполняется в десятичном формате.

Ширина

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

int ios::width(int w); // устанавливает поле ширины в w

// и возвращает предыдущую ширину

int ios::width(); // возвращает текущую ширину --

// не внося никаких изменений

Значениеwidth по умолчанию равно нулю, что эквивалентно выводу без дополнительных заполнителей. Ненулевая ширина означает, что вставки будут выполнять вывод не уже заданной ширины, ипри необходимостибудут использованы заполнители до этой ширины. Отметим, чтоусечение ширины при этом не выполняется: если указанная ширина меньше фактического числа символовдля представления вывода, то она будет проигнорирована (как при width, установленной равной нулю). Например,

int i = 123;

int old_w = cout.width(6);

cout << i; // на выводе будет bbb123, где bbb =

// пробелы. Затем ширина устанавлива-

// ется равной 0

cout.width(old_w); // восстановление предыдущей ширины // поля

Отметим, что после каждой форматированной вставки ширина очищается в ноль, так что в

int i, j;

...

cout.width(4);

cout << i << " " << j;

i будет представлена минимум четырьмя символами, однако пробел в середине выражения и j будут представлены минимально необходимым числом символов.

Манипуляторы

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

cout << setw(4) << i << setw(6) << j;

эквивалентно более широкой записи

cout.width(4);

cout << i;

cout.width(6);

cout << j;

setw представляет собой параметризованный манипулятор, объявлениекоторого находится в iomanip.h. Прочие параметризованные манипуляторы, setbase, setfill, setprecision, setiosflags и resetiosflags, работают аналогичнымобразом (см таблицу 3.1). Для того, чтобы использовать эти манипуляторы, ваша программа должна включать iomanip.h. Вы можете писать свои собственные манипуляторы, без параметров:

ostream& dingy( ostream os)

(*

return os << "\a\a";

*)

...

cout << i << dingy << j;

Манипуляторы с параметрами более сложны и требуют включения iomanip.h.

Манипуляторы Таблица 3.1

Манипулятор Синтаксис Действие

dec outs<

ins>>dec тирования с десятичными

преобразованиями

hex outs<

ins>>hex тирования с шестнадцати-

ричными преобразованиями

oct outs<

ins>>oct тирования с восьмеричными

преобразованиями

ws ins>>ws Извлечение пробельных

символов

endl outs<

строки и очистка потока

ends outs<

пустого символа в строку

flush outs<

setbase(int) outs<

ления при преобразованиях с основой n (0, 8,

10 или 16). Ноль означает по умолчанию десятичную

систему при выводе и правила С для литералов це-

лых чисел при вводе.

resetiosflags(long) ins>>resetiosflags(l) Очистка форматных битов outs<

setiosflags(long) ins>>setiosflags(l) Установка форматных битов outs<

setfill(int) ins>>setfill(n) Установка символа-за-

полнителяouts<

setprecision(int) ins>>setprecision(n) Установка точности представления outs<

setw(int) ins>>setw(n) Установка ширины поля

outs<

Не-параметризованные манипуляторы dec, hex и oct (объявленные в ios.h) непринимают никаких аргументови просто изменяют основание системы счисления при преобразовании (и оставляютэто изменение в силе):

int i = 36;

cout << dec << i << " "

<< hex << i << "

<< oct << i << endl;

// вывод на дисплей 36 24 44

Манипулятор endl вставляет символ новой строки и очищает поток. Можно также в любой момент очистить ostream, записав

ostream << flush;

Заполнители и дополнение вправо и влево

Символ-заполнитель и направление дополнения зависят от установок внутренних флагов, отвечающих за эти параметры.

По умолчанию символом-заполнителем является пробел. Изменить данное умолчание позволяет функция fill:

int i = 123;

cout.fill("*");

cout.width(6);

cout << i; // на дисплей будет выведено ***123

По умолчанию устанавливается выравнивание по правому краю (дополнение символами-заполнителями влево). Эти умолчания (а также прочие форматные флаги) можно изменять при помощи функций setf и unsetf:

int i = 56;

...

cout.width(6);

cout.fill('#');

cout.setf(ios::left,ios::adjustfield);

cout << i // на дисплей будет выведено 56####

Второй аргумент, 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 оригинала).

Характеристики

Тип файла
Документ
Размер
2,71 Mb
Тип материала
Учебное заведение
Неизвестно

Список файлов реферата

Свежие статьи
Популярно сейчас
Почему делать на заказ в разы дороже, чем купить готовую учебную работу на СтудИзбе? Наши учебные работы продаются каждый год, тогда как большинство заказов выполняются с нуля. Найдите подходящий учебный материал на СтудИзбе!
Ответы на популярные вопросы
Да! Наши авторы собирают и выкладывают те работы, которые сдаются в Вашем учебном заведении ежегодно и уже проверены преподавателями.
Да! У нас любой человек может выложить любую учебную работу и зарабатывать на её продажах! Но каждый учебный материал публикуется только после тщательной проверки администрацией.
Вернём деньги! А если быть более точными, то автору даётся немного времени на исправление, а если не исправит или выйдет время, то вернём деньги в полном объёме!
Да! На равне с готовыми студенческими работами у нас продаются услуги. Цены на услуги видны сразу, то есть Вам нужно только указать параметры и сразу можно оплачивать.
Отзывы студентов
Ставлю 10/10
Все нравится, очень удобный сайт, помогает в учебе. Кроме этого, можно заработать самому, выставляя готовые учебные материалы на продажу здесь. Рейтинги и отзывы на преподавателей очень помогают сориентироваться в начале нового семестра. Спасибо за такую функцию. Ставлю максимальную оценку.
Лучшая платформа для успешной сдачи сессии
Познакомился со СтудИзбой благодаря своему другу, очень нравится интерфейс, количество доступных файлов, цена, в общем, все прекрасно. Даже сам продаю какие-то свои работы.
Студизба ван лав ❤
Очень офигенный сайт для студентов. Много полезных учебных материалов. Пользуюсь студизбой с октября 2021 года. Серьёзных нареканий нет. Хотелось бы, что бы ввели подписочную модель и сделали материалы дешевле 300 рублей в рамках подписки бесплатными.
Отличный сайт
Лично меня всё устраивает - и покупка, и продажа; и цены, и возможность предпросмотра куска файла, и обилие бесплатных файлов (в подборках по авторам, читай, ВУЗам и факультетам). Есть определённые баги, но всё решаемо, да и администраторы реагируют в течение суток.
Маленький отзыв о большом помощнике!
Студизба спасает в те моменты, когда сроки горят, а работ накопилось достаточно. Довольно удобный сайт с простой навигацией и огромным количеством материалов.
Студ. Изба как крупнейший сборник работ для студентов
Тут дофига бывает всего полезного. Печально, что бывают предметы по которым даже одного бесплатного решения нет, но это скорее вопрос к студентам. В остальном всё здорово.
Спасательный островок
Если уже не успеваешь разобраться или застрял на каком-то задание поможет тебе быстро и недорого решить твою проблему.
Всё и так отлично
Всё очень удобно. Особенно круто, что есть система бонусов и можно выводить остатки денег. Очень много качественных бесплатных файлов.
Отзыв о системе "Студизба"
Отличная платформа для распространения работ, востребованных студентами. Хорошо налаженная и качественная работа сайта, огромная база заданий и аудитория.
Отличный помощник
Отличный сайт с кучей полезных файлов, позволяющий найти много методичек / учебников / отзывов о вузах и преподователях.
Отлично помогает студентам в любой момент для решения трудных и незамедлительных задач
Хотелось бы больше конкретной информации о преподавателях. А так в принципе хороший сайт, всегда им пользуюсь и ни разу не было желания прекратить. Хороший сайт для помощи студентам, удобный и приятный интерфейс. Из недостатков можно выделить только отсутствия небольшого количества файлов.
Спасибо за шикарный сайт
Великолепный сайт на котором студент за не большие деньги может найти помощь с дз, проектами курсовыми, лабораторными, а также узнать отзывы на преподавателей и бесплатно скачать пособия.
Популярные преподаватели
Добавляйте материалы
и зарабатывайте!
Продажи идут автоматически
6517
Авторов
на СтудИзбе
302
Средний доход
с одного платного файла
Обучение Подробнее