русс | укр

Языки программирования

ПаскальСиАссемблерJavaMatlabPhpHtmlJavaScriptCSSC#DelphiТурбо Пролог

Компьютерные сетиСистемное программное обеспечениеИнформационные технологииПрограммирование

Все о программировании


Linux Unix Алгоритмические языки Аналоговые и гибридные вычислительные устройства Архитектура микроконтроллеров Введение в разработку распределенных информационных систем Введение в численные методы Дискретная математика Информационное обслуживание пользователей Информация и моделирование в управлении производством Компьютерная графика Математическое и компьютерное моделирование Моделирование Нейрокомпьютеры Проектирование программ диагностики компьютерных систем и сетей Проектирование системных программ Системы счисления Теория статистики Теория оптимизации Уроки AutoCAD 3D Уроки базы данных Access Уроки Orcad Цифровые автоматы Шпаргалки по компьютеру Шпаргалки по программированию Экспертные системы Элементы теории информации

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


Дата добавления: 2013-12-23; просмотров: 2082; Нарушение авторских прав


Форматирование с помощью функций-членов класса ios

Перегрузка операторов извлечения

Для того, чтобы перегрузить оператор извлечения — экстрактор, используется тот же самый об­щий подход, что и для перегрузки операторов вставки — инсертеров. Например, следующий эк­страктор осуществляет ввод трехмерных координат. Обратим внимание, что он также осуществ­ляет подсказку пользователю.

// получение трехмерных координат – экстрактор

istream& operator>>(istream &stream, point &obj)

{

cout << "Enter x y z values, separating each with a space: ";

stream >> obj.x >> obj.y >> obj.z;

return stream;

}

Первым параметром должна быть ссылка на объект типа istream. Вторым параметром служит ссылка на объект, принимаю­щий ввод. Поскольку это именно ссылка, то второй аргумент может быть модифицирован при вводе информации. Экстрактор должен возвращать ссылку на объект типа istream.

Общая форма экстрактора имеет вид:

istream& operator>>(istream &поток, класс &объект)

{

// код экстрактора

return stream;

}

Следующая программа демонстрирует экстрактор для объекта класса point:

int main()

{

point a(1, 2, 3);

cout << a;

cin >> a; cout << a;

return 0;

}

Подобно функциям вставки, функции извлечения не могут быть членами класса, с элементами которого они оперируют. Как показано в примере, они могут быть друзьями или просто незави­симыми функциями. За исключением того, что экстрактор должен возвращать ссылку на объект типа istream, внутри экстрактора можно делать все, что угодно. Однако для лучшей структуриза­ции программы и ее ясности лучше всего ограничить эти действия только операциями ввода.



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

Как известно, с помощью функции printf() можно управлять форматированием информации, выводимой на экран. Например, можно указать ширину полей, левое или правое выравнивание и т.д. Все те же типы форматирования можно осуществить и в рамках ввода/вывода языка C++. Имеет­ся два способа форматирования вывода. Первый из них использует функции-члены класса ios. Второй использует специальный тип функции, называемой манипулятор. Начнем рассмотре­ние форматирования с использования функций-членов класса ios.

В заголовочном файле ios.h определены следующие переменные перечисляемого типа:

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, fixed = 0x1000, unitbuf = 0x2000, stdio = 0x4000, boolalpha = 0x8000

};

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

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

При установке флага left осуществляется вывод с левым выравниванием. Соответственно при установке флага right вывод осуществляется с правым выравниванием. По умолчанию вывод осуществляется с выравниванием по правому краю.

При установке флага internal поле, отведенное для вывода, заполняется пробелами до знака или буквы. Далее будет показано, как указать ширину поля.

Также по умолчанию численные значения выводятся в десятичной форме. Однако можно пере­определить такой способ. Например, установка флага oct задает вывод в восьме­ричной форме. Установка флага hex задает вывод в шестнадцатеричной форме. Для возвращения к десятичному выводу следует установить флаг dec.

Установка флага showbase позволяет при выводе указывать числовую базу (десятичную, восьме­ричную, шестнадцатеричную).

Установка флага showpoint приводит к выводу десятичной запятой и нулей справа для всех чисел с плавающей запятой вне зависимости, нужно это или нет.

По умолчанию при выводе научных данных, т.е. при использовании экспоненциальной формы записи чисел с плавающей запятой, используется 'е' в нижнем регистре. Также при выводе шест­надцатеричных величин символ 'x' выводится в нижнем регистре. При установке флага uppercase эти символы будут выводиться в верхнем регистре.

Установка флага showpos приводит к тому, что перед положительными числами будет выво­диться знак «плюс».

При установке флага scientific числа с плавающей запятой выводятся с использованием науч­ной нотации. При установке флага fixed числа с плавающей запятой выводятся в обычной нотации. По умолчанию, когда установлен флаг fixed, для десятичных цифр выводятся шесть позиций. Когда ни один из флагов не установлен, компилятор выбирает подходящий метод сам.

При установке флага unitbuf при каждой операции вставки данные немедленно заносятся в поток.

При установке флага stdio после каждого вывода данные заносятся в потоки stdout и stderr.

При установке флага boolalpha можно вводить и выводить данные булевого типа.

Флаги хранятся в формате длинных целых. В проекте стандарта ANSI для языка C++ этот тип обозначается как fmtflags, но в MS Visual C++ 7.0 флаги имеют тип long.

Для установки флагов используется функция setf(), чей формат имеет следующий вид:

long setf(long flags);

Эта функция возвращает предыдущее значение флага и присваивает ему зна­чение параметра flags. При этом все остальные флаги остаются неизменными. Напри­мер, для того чтобы установить флаг showbase, можно использовать следующую инструкцию:

stream.setf(ios::showbase);

Здесь stream является каким-либо потоком, на который надо оказать воздействие. Например, следующая программа устанавливает флаги showpos и scientific для cout:

#include <iostream.h>

int main()

{

cout.setf(ios::showpos);

cout.setf(ios::scientific);

cout << 123 << " " << 123.23 << " ";

return 0;

}

Данная программа выводит на экран следующие данные:

+123 +1.232300е+02

С помощью операции побитового ИЛИ можно установить одновременно столько флагов, сколько надо. Например, можно изменить программу таким образом, что будет осуществляться только один вызов функции setf() при установке обоих флагов scientific и showpos:

cout.setf(ios::scientific || ios::showpos);

Для отключения флагов надо использовать функцию unsetf(). Она имеет следующий прототип:

long unsetf(long flags);

Функция возвращает значение состояния флага и сбрасывает флаги, определяемые параметром flags.

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

long flags() const;

Эта функция возвращает текущие значения флагов, ассоциированных с тем потоком, членом ко­торого она является. Используя следующую форму функции flags(), можно установить значения флагов на указанные в параметрах flags() и возвратить предыдущие значения флагов:

long flags(long new_flags);

Для того чтобы познакомиться с работой функций flags() и unsetf(), рассмотрим следующую программу. Она включает в себя функцию, называемую showflags(), которая выводит значения флагов.

#include <iostream.h>

void showflags(long f)

{

for(long i=0x8000; i; i = i >> 1)

if(i & f) cout << “1“;

else cout << "0";

cout << "\n";

}

int main()

{

long f = cout.flags();

showflags(f);

cout.setf(ios::showpos | ios::scientific);

f = cout.flags();

showflags(f);

cout.unsetf(ios::scientific);

f = cout.flags();

showflags(f);

return 0;

}

Исполнение данной программы выдаст следующие данные:

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

int width(int len);

char fill(char ch);

int precision(int num);

Функция width() возвращает текущую ширину поля потока и устанавливает новое значение, опреде­ляемое параметром len. По умолчанию ширина поля изменяется в зависимости от числа симво­лов, необходимых для записи данных. Функция fill() возвращает текущее значение символа для заполнения, которым по умолчанию является пробел, и устанавливает текущий символ заполне­ния равным ch. Символ заполнения используется для заполнения пустых мест в соответствии с заданной спецификацией ширины поля. Функция precision() возвращает число цифр после деся­тичной запятой и устанавливает новое значение, задаваемое параметром пит. Ниже представлена программа, демонстрирующая использование этих трех функций:

#include <iostream.h>

int main()

{

cout.setf(ios::showpos | ios::scientific);

cout << 123 << " " << 123.23 << "\n";

cout.precision(2); // две цифры после запятой

cout.width(10); // поле из десяти символов

cout << 123 << " " << 123.23 << "\n";

cout.fill('#'); // заполнение символом #

cout.width(10); // поле из десяти символов

cout << 123 << " " << 123.23;

return 0;

}

Программа выдаст следующий результат:

+123 +1.232300е+02

+123 +1.23е+02

######+123 +1.23е+02

Надо помнить, что флаги одного потока независимы от флагов другого потока. Изменение флагов в одном потоке не влияет на флаги другого.

Система ввода/вывода C++ включает второй способ изменения параметров форматирования по­тока. Для этого используются специальные функции, называемые манипуляторами (manipulators), которые могут включаться в выражения ввода/вывода. Стандартные манипуляторы показаны в таблице 7.1.

Манипулятор Назначение Ввод/вывод
dec Ввод/вывод данных в десятичной форме ввод и вывод
endl Вывод символа новой строки с передачей в поток всех данных из буфера вывод
ends Вывод нулевого символа вывод
flush Сброс в поток содержимого буфера вывод
hex Ввод/вывод данных в шестнадцатеричном виде ввод и вывод
oct Ввод/вывод данных в восьмеричном виде ввод и вывод
resetiosflags(long f) Сбрасывает флаги, указанные в f ввод и вывод
setbase(int base) Устанавливает базу счисления равной параметру base вывод
setfill(int ch) Устанавливает символ заполнения равным ch вывод
setiosflags(long f) Устанавливает флаги, указанные в f ввод и вывод
setprecision(int p) Устанавливает число цифр после запятой вывод
setw(int w) Устанавливает ширину поля равной w вывод
ws Пропускает начальный символ-разделитель ввод

Таблица 7.1. Манипуляторы ввода/вывода C++

Для использования манипуляторов с параметрами в программу необходимо вклю­чить заголовочный файл iomanip.h.

Манипуляторы могут использоваться в составе выражений ввода/вывода. Ниже представлен пример программы, использующей манипуляторы для изменения формата вывода:

#include <iostream.h>

#include <iomanip.h>

int main()

{

cout << setiosflags(ios::fixed) << setprecision(2) << 1000.243 << endl;

cout << setw(20) << "Hello there.";

return 0;

}

Программа выводит следующие данные:

1000.24

Hello there.

Обратим внимание, как манипуляторы появляются в последовательности операторов ввода/выво­да. Когда манипуляторы не имеют аргументов, как манипулятор endl в этой программе, за ними не следуют скобки. Причина этого в том, что оператору << передается адрес манипулятора.

Следующая программа использует функцию setiosflags() для установки флагов scientific и showpos потока cout:

int main()

{

cout << setiosflags(ios::showpos) << setiosflags(ios::scientific);

cout << 123 << " " << 123.23;

return 0;

}

Следующая программа использует манипулятор ws для пропуска идущих вначале символов-разделителей при вводе строки в переменную s:

int main()

{

char s[80];

cin >> ws >> s;

cout << s;

}



<== предыдущая лекция | следующая лекция ==>
Создание операторов вставки | Создание манипуляторов без параметров


Карта сайта Карта сайта укр


Уроки php mysql Программирование

Онлайн система счисления Калькулятор онлайн обычный Инженерный калькулятор онлайн Замена русских букв на английские для вебмастеров Замена русских букв на английские

Аппаратное и программное обеспечение Графика и компьютерная сфера Интегрированная геоинформационная система Интернет Компьютер Комплектующие компьютера Лекции Методы и средства измерений неэлектрических величин Обслуживание компьютерных и периферийных устройств Операционные системы Параллельное программирование Проектирование электронных средств Периферийные устройства Полезные ресурсы для программистов Программы для программистов Статьи для программистов Cтруктура и организация данных


 


Не нашли то, что искали? Google вам в помощь!

 
 

© life-prog.ru При использовании материалов прямая ссылка на сайт обязательна.

Генерация страницы за: 0.008 сек.