Мы поможем в написании ваших работ!



ЗНАЕТЕ ЛИ ВЫ?

Тонкости использования потоков ввода-вывода

Поиск

С помощью перегрузки операторов ввода и вывода в поток «и» вы можете заставить компилятор рас­познавать в операторах ввода-вывода один или несколько необходимых вам классов. В следующем разделе по­ясняется, как создать потоковые классы, и рассматриваются другие тонкости использования потоков.

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

В заголовочном файле IOSTREAM.H содержатся следующие объявления одного потока ввода и трех пото­ков вывода:

extern istream_withassign_Cdecl cin; // Объект потока ввода

extern ostream_withassign_Cdecl cout; // Объект потока вывода

extern ostream_withassign_Cdecl cerr; // Объект потока вывода ошибок

extern ostream_withassign_Cdecl clog; // Объект буферизованного потока вывода ошибок

Классы istream_withassign и ostream_withassign в конечном счете выводятся из "прадедушки" классов по­тока ввода-вывода — ios. Вам не надо вникать во все детали реализации этих классов для того, чтобы исполь­зовать их в программах, однако, если вам интересно, в поставку Borland C++ входят полные и пространные файлы с исходными текстами реализации потоков ввода-вывода.

Потоковые классы выполняют форматированный ввод-вывод со встроенной поддержкой обработки оши­бок. Потоки ввода-вывода поддерживают базовые типы данных, подобные char, short, int, long, char* (напри­мер, символьная строка, завершающаяся нулем), float, double, long double и void* (отображается как значение-адрес).

Имейте в виду, что cin, cout, cerr и clog — объекты классов. В соответствующих им классах определены перегруженные операторы потоков ввода и вывода, что позволяет использовать операторы ввода-вывода в по­ток следующим образом:

cin >> v; // Прочитать v из стандартного ввода

cout << v; // Записать v в стандартный вывод

Как вы увидите в других примерах, операторы ввода-вывода можно использовать каскадом, как в следую­щем выражении:

cout << "Balance == $" << balance < " (dollars)\n";

Для форматирования вывода вы можете установить один или несколько флагов в объекте потока ввода-вы­вода (см. объявление класса ios в заголовочном файле IOSTREAM.H). Следует использовать функции-члены flagsO, setfO и unsetfO для управления состоянием этих флагов. Например, для вывода беззнакового значения в шестнадцатеричной форме следует установить флаг hex в cout путем следующего обращения к функции-члену setfO класса ios:

unsigned v = 12345;

cout «"Before: " «v «'\n'; // Вывод по умолчанию (десятичный)

cout.setf(cout.hex); // Модификация потока вывода

cout «"After: " «v «'\n' // Шестнадцатеричный вывод

Несмотря на то что это сработает, как показано дальше, существуют более простые способы форматирова­ния потока вывода.

Использование манипуляторов

Подключение заголовочного файла IOMANIP.H (в котором при необходимости включается заголовочный файл IOSTREAM.H) делает возможным использование нескольких манипуляторов, полезных для создания форматированного вывода и чтения форматированного ввода. Например, вы можете использовать манипуля­тор hex для вывода значения в шестнадцатеричной форме:

unsigned v = 12345;

cout «"In hexadecimal v == " «hex «v «'\n';

cout «"In decimal v == " «dec «v «'\r\'\

В последней строке используется манипулятор dec для возвращения cout в состояние форматированного вывода в десятичной форме. Вы также можете манипулировать потоками ввода. Следующие операторы чита­ют шестнадцатеричное значение и выводят его же в десятичной форме:

cout «"Enter value in hex: ";

cin» hex» v;

cout «"Value in decimal == " «dec «v;

В табл. 15.2 перечислены манипуляторы ввода-вывода, определенные в заголовочных файлах IOMANIP.H и IOSTREAM.H.

Некоторые манипуляторы используются с параметрами. Например, манипулятор setbaseGnt n) формати­рует значение в системе счисления с основанием п. (Если п — нуль, вывод по умолчанию становится деся­тичным, а ввод по умолчанию соответствует спецификациям ANSI С для символьного представления целочис­ленных значений.)

Таблица 15.2. Манипуляторы потоков ввода-вывода

 

Манипулятор Действие
dec Преобразовать в десятичную систему счисления
endl Начать новую строку; вывести буфер потока
ends Вставить нулевой завершающий символ в строку
flush Выполнить довывод в поток
hex Преобразовать в шестнадцатеричную систему счисления
lock(ios &r) Заблокировать дескриптор файла для ссылки гг на поток вво­да-вывода
Манипулятор Действие
oct Преобразовать в восьмеричную систему счисления
resetiosflags(long f) Очистить биты форматирования, заданные в /
setbase(int n) Установить систему счисления с основанием п (0, 8, 10 или 16)
setiosflags(long f) Установить биты форматирования, заданные в f
setfilKint c) Использовать символ с для заполнения при выравнивании
setprecision(int n) Установить точность вывода значений с плавающей точкой равной и
setwGnt n) Установить ширину поля и
unlockGos &ir) Разблокировать дескриптор файла для ссылки ir потоков вво­да-вывода
ws Извлечь пробельные символы

 

Манипуляторы-функции потоков вывода возвращают значения типа ostream&, другими словами, ссылки на объект ostream. Вы можете написать свои собственные манипуляторы, включив заголовочный файл IOSTREAM.H и определив функцию типа &ostream. Например, вы можете определить манипулятор звонка для потока вывода следующим образом:

ostream& bell(ostream& os) {

return os «"\a"; // '\a' - управляющий код звонка}

Функция bell() имеет тип &ostream, и в ней объявлен параметр os типа ostream&. Это позволит использо­вать функцию в каскадном оперторе вывода в поток:

cout «bell «"Ding!";

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

cout.width(8); // Отобразить v в восьми позициях

cout << v «'\n'; // Отобразить v с выравниванием по умолчанию

cout «v «'\n';

 

Модификатор width недолговечен, он оказывает влияние только на следующее выводимое значение. Другие функции-члены используют функцию fill(charc), устанавливающую символ заполнения при выравнива­нии с помощью символьного параметра с, и precisionGnt n), устанавливающую точность вывода значений с
плавающей точкой равной п.

Перегрузка оператора

Вывода в поток

Обычно потоки вывода могут поддерживать лишь базовые типы данных, подобные int, long, double, char* и т.д.

С помощью перегрузки оператора вывода в поток <<, можно заставить выражения, в которых используются эти операторы, выводить объекты ваших собственных классов.

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

Листинг 15.8. POINTOUT.CPP

(классы и операторы вывода)

«include <iostream.h>

// объявляется потоковый класс

//с именем TPoint

class TPoint {

private:

int x, y;

public:

TPointO { x = у = 0; }

TPoint(int xx, int yy) { x = xx; у = yy; }

void PutX(int xx) { x = xx; }

void PutY(int yy) { у = yy; }

int GetX(void) { return x; }

int GetY(void) { return y; }

// перегружается оператор

//вывода в поток

friend ostream&

operator<<(ostream& os, TPoint &p);

}

Main()

{ TPoint p;

//// исп-ние парагруженного

// оператора вывода в поток

cout «p «‘\n’

p.PutX(100);

p.PutY(200);

cout «p «‘\n’

return 0;

}

// возвращает значения типа ostream&,

//объявлены два параметра — os типа ostream& и ссылка р на объект класса TPoint.

ostream& operator«(ostream& os, TPoint &p) {

os «"x == " << p.x «", у == " «p.у;

return os;

}

В строке 13 путем объявления дружественной функции-члена operator<<) перегружается оператор вывода в поток. Эта дружественная функция-член возвращает значения типа ostream&, и в ней объявлены два пара­метра — os типа ostream& и ссылка р на объект класса TPoint.

Поскольку функция operator«() — друг класса TPoint, оператор в строке 29 имеет непосредственный доступ к данным-членам х и у объекта, на который ссылается ссылка р. Обратите внимание, что всю строку занимает один оператор вывода в поток, выводящий через ссылку os типа ostream значения двух данных-чле­нов плюс две символьные строки. В конце концов, функция возвращает ссылку os.

Запуск программы на вы­полнение приведет к следующим результатам:

х == 0, у == 0

х == 100, у == 200

Поскольку функция operator<<() возвращает ссылку на ostream, можно выводить несколько объектов в одном операторе вывода в поток. Например, если p1, р2 и рЗ — объекты класса TPoint, можно отобразить их значения следующим образом:

out «р1 «"; " «р2 «"; " «рЗ;

эти операторы выполняются путем обращения к нескольким функциям, реализующим пере­грузку оператора вывода в поток.

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

((((cout «р1) «"; ") «р2) «"; ") «рЗ;

 

 



Поделиться:


Последнее изменение этой страницы: 2016-08-01; просмотров: 354; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 18.218.55.223 (0.008 с.)