Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Язык программирования Сpp 25.09.11 (2).doc
Скачиваний:
16
Добавлен:
19.08.2019
Размер:
10.09 Mб
Скачать

Управление потоком ввода-вывода

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

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

Для ссылки на флаг используется функция потокового класса setf(имя_флага). Функция-член с именем setf()(сокращение от set flag – установить флаг) класса ofsteam позволяет установить флаги, некоторые из них описаны в приведенной ниже таблице. Функция-член с именем unsetf() напротив дает возможность сбросить флаг.

Флаг

Значение

Состояние по умолчанию

ios::fixed

Установка флага приводит к тому, что числа с плавающей точкой не используют запись с основанием e. Установка флага автоматически сбрасывает флаг ios::scrintific.

Сброшен

ios::scientific

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

Сброшен

ios::showpoint

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

Сброшен

ios::showpos

При установке флага перед положительными числами выводится знак “+”. Знак минус перед отрицательными числами ставится всегда, независимо от установки флагов.

Сброшен

ios::right

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

Установлен

ios::left

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

Сброшен

Для управления флагами в классе ios есть методы flags, setf и unsetf.

Перед осуществлением вывода можно установить несколько флагов. Пусть в программе организован поток с именем outStream. Ниже приведен фрагмент программы с установкой флагов для этого потока

outStream.setf(ios::scientific); //выводимые числа будут

// представлены с использованием е

outStream.setf(ios::showpoints); //используется десятичная точка

outStream.setf(ios::showpos); //перед положительными числами

//ставится +

Для управления выводом используется несколько функций-членов класса ofsteam. Одна из таких функций нам уже встречалась, это функция precision(int n). Применение этой функции приводит к тому, что любое число с десятичной точкой будет выводиться в поток с n значащими цифрами после десятичной точки. Например, если имеется поток outStream, то после инструкции

outStream.precision(2);

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

outStream.precision(3);

Вот пример программы с использованием флагов. Программа рассчитывает выражение для 10 значений n от 0 до 9

#include <iostream>

#include <cmath>

#include <fstream>

#define pi 3.1415926

using namespace std;

main(){

ifstream inStream;//объявление потоков

ofstream outStream;

long double db1[10], db2[10];

outStream.open("character.dat"); //присоединение к файлу

for(int n=0;n<10;n++){

db1[n]=100*sin(pi/(n+1));

outStream<<db1[n]<<"\n";

}

outStream.close(); //закрытие потоков

inStream.open("character.dat"); //присоединение к файлу

if (inStream.fail()){

//Печать сообщения об ошибке

cout<<"Не удается открыть файл character.dat\n";

exit(1);// Функция аварийного завершения.

}

for(int i=0; i<10;i++)

inStream>> db2[i];

inStream.close(); //закрытие потоков

cout.width(20); //для вывода числа отводится 20 позиций

cout.setf(ios::right); //Выравнивание по правому краю

cout.setf(ios::fixed); /*выводимые числа представлены в

форме c фиксированной точкой*/

cout.setf(ios::showpos); //перед положительным числом знак +

for(int i=0; i<10;i++)

cout<<db2[i]<<endl;

char z;

cin>>z;

}

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

Попробуйте теперь применить выравнивание по левому краю и сравните результаты.

Очень удобной функцией форматирования в потоке cout является функция width(интервал). Этой функцией мы уже воспользовались в предыдущем примере, а теперь поясним, как она работает.

Функция width() позволяет отвести количество символов для вывода числа, точнее расстояние от начала печати. Если количество выводимых символов окажется большим, то функция на количество выводимых разрядов не влияет. Вот пример программы

#include <iostream>

using namespace std;

#include <windows>

main(){

SetConsoleOutputCP(1251);

int a=1;

while(a<1000000){ //организация условно-бесконечного цикла

cout<<"Введите целое число a=";

cin>>a;

cout.width(4);

cout<<a<<endl;

}

}

Вот результат

Видно, что при выводе для результата отводится 4 позиции. Свободные позиции заполняются пробелами. Если выделенных позиций не хватает, то интервал увеличивается на число необходимых позиций.