Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ООП Лекции PDF / ООП 10 Лек Потоковый ввод-вывод.pdf
Скачиваний:
63
Добавлен:
15.02.2015
Размер:
447.65 Кб
Скачать

Лекция 10

Потоковый ввод-вывод

5

Для переменной типа char* (рассматриваемого как строка) оператор >> пропускает символызаполнители и сохраняет следующие за ними символы, пока не появится следующий символ-заполнитель. Затем в указанную переменную добавляется нуль-символ.

ФОРМАТИРОВАНИЕ ПОТОКА

До сих пор мы использовали для вывода информации во всех примерах форматы, заданные в C++ по умолчанию. Для управления форматированием библиотека ввода-вывода предусматривает три вида средств: форматирующие функции, флаги и манипуляторы. Все эти средства являются членами класса basic_ios и потому доступны для всех потоков.

Форматирующие функции-члены

Рассмотрим вначале форматирующие функции-члены. Их всего три: width ( ), precision ( ) и fill ( ).

По умолчанию при выводе любого значения оно занимает столько позиций, сколько символов выводится. Функция width ( ) позволяет задать минимальную ширину поля для вывода значения. При вводе она задает максимальное число читаемых символов. Если выводимое значение имеет меньше символов, чем заданная ширина поля, то оно дополняется символами-заполнителями до заданной ширины (по умолчанию – пробелами). Однако если выводимое значение имеет больше символов, чем ширина отведенного ему поля, то поле будет расширено до нужного размера. Эта функция имеет следующие прототипы:

streamsize width ( streamsize wide ) ; streamsize width ( ) const ;

Тип streamsize определен в заголовочном файле <iostream.h> как целочисленный. Функция с первым прототипом задает ширину поля wide, а возвращает предыдущее значение ширины поля. Функция со вторым прототипом возвращает текущее значение ширины поля. По умолчанию она равна нулю, то есть вывод не дополняется и не обрезается. В ряде компиляторов после выполнения каждой операция вывода значение ширины поля возвращается к значению, заданному по умолчанию.

Функция precision ( ) позволяет узнать или задать точность (число выводимых цифр после запятой), с которой выводятся числа с плавающей точкой. По умолчанию числа с плавающей точкой выводятся с точностью, равной шести цифрам. Функция имеет precision ( ) следующие прототипы:

streamsize precision ( streamsize prec ) ; streamsize precision ( ) const ;

Функция с первым прототипом устанавливает точность равной ргес и возвращает предыдущую точность. Функция со вторым прототипом возвращает текущую точность.

Замечание. Если не установлен флаг scientific или fixed (оба эти флага рассматриваются далее), то precision ( ) задает общее число цифр.

Функция fill ( ) позволяет прочесть или установить символ-заполнитель. Она имеет следующие прототипы:

char_type fill ( char_type ch ) ; char_type fill ( ) const ;

Функция с первым прототипом устанавливает ch в качестве текущего символа-заполнителя и возвращает предыдущий символ-заполнитель. Функция со вторым прототипом возвращает текущий символзаполнитель. По умолчанию в качестве символа-заполнителя используется пробел. Тип данных char_type является параметром класса basic_ios и может обозначать набор "узких" или "широких" символов.

Рассмотрим пример программы, в котором используются форматирующие функции:

#include <iostream.h> #include <math.h> void main ( )

{

double x ; cout.precision ( 4 ) ; cout.fill ( '0' ) ;

cout << "x\tsqrt(x)\tх^2\n" ; for ( x = l.0 ; x<=6 . 0 ; x++ )

{

cout. width (4) ; cout << x << ’\t’ ; cout.width ( 6 ) ;

Выжол Ю.А.

Объектно-ориентированное программирование

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

Лекция 10

Потоковый ввод-вывод

6

cout << sqrt ( x ) << ’\t’ ; cout.width ( 3 ) ;

cout << x*x << ' \n ' ;

}

}

Эта программа выводит на экран небольшую таблицу значений переменной х, ее квадратного корня и квадрата:

x

sqrt(x)

x^2

0001

0000001

001

0002

001.414

004

0003

001.732

009

0004

002.000

016

0005

002.236

025

0006

002.449

036

Флаги форматирования

С каждым потоком связан набор флагов, которые управляют форматированием потока. Они представляют собой битовые маски, которые определены в классе ios как данные enum-типа fmt_flags. Сами флаги принадлежат типу fmtf lags, который определен следующим образом:

typedef int

fmtflags ;

Флаги форматирования имеют следующее назначение:

boolalpha

значения булевского типа вставляются и извлекаются в виде слов true и false

hex

значения целого типа преобразуются к основанию 16 (как шестнадцатеричные)

dec

значения целого типа преобразуются к основанию 10

oct

значения целого типа преобразуются к основанию 8 (как восьмеричные)

basefield = dec | oct | hex

флаги dec, oct и hex взаимно исключают друг друга

fixed

числа с плавающей точкой выводятся в формате с фиксированной точкой

scientific

числа с плавающей точкой выводятся в научной записи (т.е., +n.хххЕ+уу)

floatfield = scientific | fixed

флаги scientific и fixed взаимно исключают друг друга

showbase

выводится основание системы счисления в виде префикса к целому числовому значе-

showpoint

нию (например, число 10FE выводится как Ох10FЕ)

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

showpos

нули

 

при выводе положительных числовых значений выводится знак плюс

uppercase

заменяет определенные символы нижнего регистра на символы верхнего регистра

 

(символ "е" при выводе чисел в научной нотации на "Е" и символ "х" при выводе 16-

left

ричных чисел на "X")

данные при выводе выравниваются по левому краю поля

right

данные при выводе выравниваются по правому краю поля

internal

добавляются символы-заполнители между всеми цифрами и знаками числа для запол-

 

нения поля вывода

adjustfield = left | right | internal флаги left и right взаимно исключают друг друга skipws

unitbuf

Прочесть текущие установки флагов позволяет функция-член flags ( ) класса ios. Для этого используется следующий прототип этой функции:

fmtflags flags ( ) const ;

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

fmtflags flags ( fmtflags fmtfl ) ;

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

Выжол Ю.А.

Объектно-ориентированное программирование

Лекция 10

Потоковый ввод-вывод

7

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

fmtflags setf ( fmtflags mask ) ;

fmtflags setf ( fmtflags fmtfl , fmtflags mask ) ;

Первая функция-член неявно вызывает функцию flags ( mask | flags ( )) для установки битов, указанных параметром mask, и возвращает предыдущие значения флагов. Второй вариант функции присваивает битам, указанным параметром mask, значения битов параметра fmtfl, а затем возвращает предыдущие значения флагов. Например, следующий вызов функции setf ( ) устанавливает для потока cout флаги hex

и uppercase:

cout.setf ( ios :: hex | ios :: uppercase ) ;

Сбросить установленные флаги можно с помощью функции-члена unsetf ( ) класса ios, имеющей следующий прототип:

void unsetf ( fmtflags mask ) ;

Она сбрасывает флаги, заданные параметром mask. Следующий пример демонстрирует некоторые флаги:

#include <iostream>

 

 

void main ( )

 

 

{

 

 

double d = 1.321e9 ;

int n = 1024 ;

 

cout << "d = " << d << "\tn = " << n << ' \n ' ;

// выводит значения

cout.setf ( ios :: hex | ios :: uppercase ) ;

// изменяет флаги

cout.setf ( ios :: showpos ) ;

 

cout << "d = " << d << "\tn = " << n << ' \n ' ;

// выводит значения снова

}

 

 

При выполнении программа выводит на экран:

d = 1.321е+09

n = 1024

d = +1.321Е+09

n = +1024

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

Система ввода-вывода C++ предусматривает еще один способ форматирования потока. Этот способ основан на использовании манипуляторов ввода-вывода. Манипуляторы ввода-вывода представляют собой просто вид функций-членов класса ios, которые, в отличие от обычных функций-членов, могут располагаться внутри инструкций ввода-вывода. В связи с этим ими пользоваться обычно удобнее.

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

endl

вставляет символ конца строки и очищает буфер;

ends

вставляет символ конца строки;

flush

очищает буфер потока;

left

устанавливает флаг left;

right

устанавливает флаг right;

internal

устанавливает флаг internal;

fixed

устанавливает флаг fixed;

scientific

устанавливает флаг scientific;

showbase

устанавливает флаг showbase;

noshowbase

сбрасывает флаг showbase;

showpoint

устанавливает флаг showpoint;

noshowpoint

сбрасывает флаг showpoint;

showpos

устанавливает флаг showpos;

noshowpos

сбрасывает флаг showpos;

unitbuf

устанавливает флаг unitbuf;

nounitbuf

сбрасывает флаг unitbuf;

uppercase

устанавливает флаг uppercase;

nouppercase

сбрасывает флаг uppercase.

Манипуляторы ввода-вывода имеют следующее назначение:

boolalpha

устанавливает флаг boolalpha;

noboolalpha

сбрасывает флаг boolalpha;

Выжол Ю.А.

Объектно-ориентированное программирование