lab6 (1080919), страница 2
Текст из файла (страница 2)
int precision();
возвращает текущее значение точности представления при выводе вещественных чисел (типа float и double);
int precision(int n);
устанавливает по значению параметра n точность представления вещественных чисел, возвращает предыдущее значение точности;
long setf(long);
устанавливает флаги в соответствии с тем, как они помечены в фактическом параметре. Возвращает предыдущую установку флагов;
long setf(long _setbits, long _field);
устанавливает флаги в соответствии со значениями параметров. Биты, помеченные в параметре _field, сбрасываются (очищаются), а затем устанавливаются те биты, которые отмечены в параметре _setbits;
long unsetf(long);
сбрасываются (очищаются) все биты флагов, которые помечены в параметре. Функция возвращает предыдущее значение флагов;
int width();
возвращает установленное значение ширины поля;
int width(int);
устанавливает значение ширины поля в соответствии со значением параметра;
Объяснять тонкости применения перечисленных компонентов класса ios нужно на примерах, причем понимание смысла и значимости отдельных компонент приходит только с учетом их взаимосвязей.
В следующей программе демонстрируются основные принципы форматирования с помощью компонентных функций класса ios. Отметим, что определение класса ios включается в программу автоматически, так как файл iostream содержит описания классов, производных от класса ios.
//Р11-02.СРР - форматирование выводимой информации
#include <iostream>
using namespace std;
void main ()
{ char name[] = "Строка длиной 52 символа в поле шириной 58 позиций.";
cout << "\n\n";
cout.width(58); // Ширина поля вывода для потока cout
// Символ заполнения пустых позиций поля:
cout.fill('$' ) ;
// Первый вывод строки в поток cout:
cout << name << endl;
cout.width(58); // Убрать нельзя
// Заполнитель между знаком и значением:
cout.setf(ios::internal);
double dd = -33.4455;
cout <<dd << endl; // Вывод вещественного значения
cout.width(58); // Убрать нельзя
// Смена выравнивания:
cout.setf(ios::left,ios::adjustfield);
// Символ заполнения пустых позиций поля:
cout.fill('#') ;
// Второй вывод строки в поток cout:
cout << name << endl;
long nn = 90000; // Шестнадцатеричное значение 0x15f9C
// Смена основания счисления:
cout.setf(ios::hex,ios::basefield);
// Выводить признак основания счисления:
cout.setf(ios::showbase);
// Переход на верхний регистр:
cout.setf(ios::uppercase);
cout.width(58); // Убрать нельзя
cout << nn << endl; // Вывод целого значения типа long
cout.width (58); // Убрать нельзя
// Смена выравнивания:
cout.setf(ios::internal,ios::adjustfield);
// Символ заполнения пустых позиций поля:
cout.fill('$') ;
cout.unsetf(0x0200); //' Переход на нижний регистр
cout <<nn << endl; // Вывод целого значения типа long
}
Результат выполнения программы:
$$$$$$ Строка длиной 52 символа в поле шириной 58 позиций.
-$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$33.4455
Строка длиной 52 символа в поле шириной 58 позиций.######
0X15F90################################################# 0x$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$15f90
Прокомментируем программу и результаты. По умолчанию ширина поля вывода устанавливается равной длине принятого представления выводимого значения. Поэтому действие функции width () однократное, и ее нужно при каждом выводе значения явно использовать, если умалчиваемое значение ширины поля вывода не устраивает программиста. Функция fill () устанавливает символ заполнения пустых позиций поля. При первом выводе строки name [ ] по умолчанию установлено выравнивание по правому краю поля, и символы ' $' помещены слева от содержимого строки. Перед выводом значения вещественной переменной dd функцией setf() установлен флаг internal. Под его влиянием символ заполнения разместился между знаком ' - ' и числовым значением 33.4455. Ширина поля явно указана в 58 позиций.
Перед вторым выводом строки name[ ] "под влиянием" второго параметра (adjustfield) функции setf () сброшены флаги right и internal и явно установлен флаг left выравнивания по левому краю. Изменен символ заполнения пустых позиций ‘ # ‘. Перед выводом длинного целого числа nn установлено основание системы счисления (basefieid - сбрасывает флаги оснований счисления; hex -явно устанавливает шестнадцатеричное основание). Установлены флаги showbase и uppercase и ширина поля вывода.
Число 90000 выведено в шестнадцатеричном виде, признаком 0х обозначено основание системы счисления, для изображения шестнадцатеричных цифр и признака основания используются прописные буквы. Так как при переходе к выравниванию по левому краю флаг internal оказался сброшенным, то символ заполнения ' # ' размещен не после признака основания счисления 0х, а заполняет правую пустую часть поля. Заключительный вывод значения nn, равного 90000, выполнен с флагами internal и left. Для перехода на нижний регистр использована функция unsetf () с явным значением флага uppercase.
Манипуляторы. Несмотря на гибкость и большие возможности управления форматами с помощью компонентных функций класса ios, их применение достаточно громоздко. Более простой способ изменения параметров и флагов форматирования обеспечивают манипуляторы, к возможностям которых мы перейдем.
Манипуляторами называют специальные функции, позволяющие программисту изменять состояния и флаги потока. Особенность манипуляторов и их отличие от обычных функций состоит в том, что их имена (без параметров) и вызовы (с параметрами) можно использовать в качестве правого операнда для операции обмена (<< или >>). В качестве левого операнда в этом выражении, как обычно, используется поток (ссылка на поток), и именно на этот поток оказывает влияние манипулятор.
Например, манипулятор hex позволяет устанавливать шестнадцатеричное основание счисления выводимых в поток cout числовых значений. Выполнив последовательность операторов:
cout << "\пДесятичное число: "<< 15 << hex;
cout << "\пШестнадцатеричное представление: "<< 15;
получим на экране:
Десятичное число: 15
Шестнадцатеричное представление: 0xF
Как наглядно показывает результат, применение манипулятора hex изменило одно из свойств потока cout. Десятичная целая константа 15 воспринимается и выводится на экран в шестнадцатеричном виде.
В качестве примера каждый манипулятор автоматически (без явного участия программиста) получает ссылку на тот поток, с которым он используется в выражении. После выполнения манипулятора он возвращает ссылку на тот же поток. Поэтому манипуляторы можно использовать в цепочке включений в поток или извлечений из потока. При выполнении манипулятора никаких обменов данными с потоком не происходит, но манипулятор изменяет состояние потока. Например, выполнив оператор с манипуляторами hex, oct, dec:
cout << 15 << hex << 15 << oct << 15 << dec<< 15;
в качестве результата получим:
150xF01715
Манипуляторы библиотеки классов ввода-вывода языка Си++ делятся на две группы: манипуляторы с параметрами и манипуляторы без параметров.
Манипуляторы без параметров:
dec - при вводе и выводе устанавливает флаг десятичной системы счисления;
hex - при вводе и выводе устанавливает флаг шестнадцатеричной системы счисления;
oct - при вводе и выводе устанавливает флаг восьмеричной системы счисления;
ws - действует только при вводе и предусматривает извлечение из входного потока пробельных символов (пробел, знаки табуляции '\t’ и ' \v’, символ перевода строки '\n', символ возврата каретки '\r', символ перевода страницы’ \f’);
endl - действует только при выводе, обеспечивает включение в выходной поток символа новой строки и сбрасывает буфер (выгружает содержимое) этого потока;
ends - действует только при выводе и обеспечивает включение в поток нулевого признака конца строки;
flush - действует только при выводе и очищает выходной поток, т.е. сбрасывает его буфер (выгружает содержимое буфера).
left - вывод значения с левым выравниванием (прижать к левому краю поля);
right - вывод значения с правым выравниванием (это значение устанавливается по умолчанию);
fixed - для вещественных чисел (типов float, double) использовать представление в формате с фиксированной точкой, причем количество цифр дробной части определяется заданной точностью.
Обратите внимание, что не все перечисленные манипуляторы действуют как на входные, так и на выходные потоки, ws действует только при вводе; endl, ends, flush - только при выводе.
Манипуляторы dec, hex, oct, задающие основание системы счисления, изменяют состояние потока, и это изменение остается в силе до следующего явного изменения.
Манипулятор endl рекомендуется использовать при каждом выводе, который должен быть незамедлительно воспринят пользователем. Например, его использование просто необходимо в таком операторе:
cout << "Ждите! Идет набор статистики." << endl ;
При отсутствии endl здесь нельзя гарантировать, что сообщение пользователю не останется в буфере потока cout до окончания набора статистики.
Рекомендуется с помощью манипулятора flush сбрасывать буфер выходного потока при выводе на экран подсказки до последующего ввода информации:
cout << "Введите название файла:" << flush;
cin >> fileName; // Здесь fileName - символьный массив
Манипуляторы с параметрами определены в файле iomanip:
setbase(int n);
устанавливает основание (n) системы счисления. Значениями параметра n могут быть: 8, 10 или 16.
resetiosflags(long L)
сбрасывает (очищает) отдельные флаги состояния потоков ввода и вывода на основе битового представления значения параметра L (сбрасывает флаги в соответствии с единичными битами);
setiosflags(long L)
устанавливает отдельные флаги состояния (форматные биты) потоков ввода-вывода на основе битового представления значения параметрах (устанавливаются флаги в соответствии с единичными битами параметра);
setfill(int n)
значение параметра n в дальнейшем используется в качестве кода символа-заполнителя, который помещается в незанятых позициях поля при вводе значения. (См. компонент x_fill класса ios.);
setprecision(int n)
определяет с помощью значения параметра n точность представления вещественных чисел, т.е. максимальное количество цифр дробной части числа при вводе и выводе. (См. компонент x_precision класса ios.);
setw(int n)
значение параметра n задает минимальную ширину поля вывода. (См. компонент x_width класса ios.)
С помощью манипуляторов можно управлять представлением информации в выходном потоке. Например, манипулятор setw(int n) позволит выделить для числового значения поле фиксированной ширины, что удобно при печати таблиц.