Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Основы алгоритмизации и программирования .Язык си.pdf
Скачиваний:
104
Добавлен:
16.03.2016
Размер:
4.49 Mб
Скачать
16.2. Управление выводом

ГЛАВА 16. Переход к ООП

При переходе от языка Си к языку С++ в стандарт ANSI были введены дополнительные механизмы, которые позволили в конечном итоге создать среду для разработки программ в объектно-ориентированном стиле.

Рассмотрим некоторые из них.

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

Поток – это абстрактное понятие, которое относится к любому переносу данных от источника к приемнику. Потоки С++ обеспечивают надежную работу как со стандартными (stdin, stdout), так и с определенными

пользователями типами данных. Поток определяется как последовательность

байт, не зависящая от конкретного устройства.

 

 

 

Р

 

 

 

 

Для ввода-вывода

в языке С++

используются два объекта класса

 

 

 

 

 

 

 

 

 

 

 

 

 

 

И

iostream: cin (класс istream), cout (класс ostream) и две переопределенные

операции

 

побитового сдвига.

Для

их

 

работы необходимо подключить

заголовочный файл iostream.h.

 

 

 

 

 

 

 

У

 

 

 

 

 

 

 

Г

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Формат записи операций помещения в поток << (вывод на экран) и

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

 

 

 

 

cout <<

ID переменной ;

 

 

Б

 

 

 

 

 

а

 

 

 

 

 

 

cin >> ID переменной ;

 

 

 

 

Стандартный поток вывода cout

 

 

 

 

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

 

 

 

 

 

 

 

 

к

 

 

 

 

 

устройством вывода stdout (диспл й монитора), а ввода cin – со стандартным

устройством ввода stdin,

.е. клавиа урой. Приведем пример:

 

#include<iostream.h>

 

 

е

 

 

 

 

 

 

 

 

т

 

 

 

 

 

 

 

 

void main (void)

 

 

 

 

 

 

 

 

 

{

i, j, k;

 

 

 

 

 

 

 

 

 

 

int

 

о

 

 

// «end line» – переход на новую строку

cout << “ Hello! ” << endl;

 

 

 

 

и

 

 

 

 

 

 

 

 

 

 

 

cout << “ Input

i, j ”;

 

 

 

 

 

 

 

 

 

 

cin

>> i >> j ;

 

 

 

 

 

 

 

 

 

 

 

 

 

 

л

 

 

 

 

 

 

 

 

 

 

 

 

k = i + j ;

 

 

 

 

 

 

 

 

 

 

 

 

 

coutб<< “ Sum i , j = “ << k << endl;

 

 

 

 

 

 

и

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Б

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

}

В стандарте языка Си ANSI ввод-вывод данных осуществляется при помощи стандартных библиотечных функций. Управление выводом осуществляется при помощи использования форматов и управляющих символов.

Для форматирования и управления выводом данных в потоке введен механизм манипуляторов – специальных функций для модификации работы

168

cout << b << endl;
cout << setprecision(3) << b << endl;
// На экране: 1.55555

потока, предназначенных для форматирования данных, как при выводе, так и в оперативной памяти.

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

 

 

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

специальные

функции,

возвращающие

модифицированные данные потока. В большинстве случаев их использование позволяет форматировать данные, как при выводе, так и в оперативной памяти.

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

Рассмотрим работу некоторых манипуляторов на конкретном примере.

#include<iomanip.h>

 

 

Р

main()

 

 

 

И

{

 

int a = 157;

 

У

 

double b = 1.55555;

 

cout << setw(10) << a << endl;

 

Г

 

 

 

 

 

/* Манипулятор setw(n) – устанавливает ширину поля, т.е. n позиций, для

вывода объекта. На экране объект а будет выводиться с 8-й позиции, первые

 

Б

7 позиций – пустые: 157 (заполнение пробел ми неиспользуемой части).

Действует только для следующего за ним объекта. */

а

к

 

/* Манипулятор setwfill(kod) – усеанавливает заполнитель пробелов, заданный символом или его кодом (можно было указать 122 – код символа 'z'). На экране: zzzzzzz157. Дейс ву до изменения или отмены setwfill(0) .*/

cout << setw(10) << setfill(‘z’) << a << endl;

cout << oct << a <<етendl;

/* Манипулятор oct – вып лняет преобразование объекта в 8-ричную форму

 

 

о

представления. На экране: 235 */

 

и

 

cout << hex << a << endl;

 

л

 

// hex – прео разует объект в 16-ричную форму. На экране: 9d

 

бcout << dec << a << endl;

// dec и– преобразует обратно в 10-тичную. На экране: 157

Б

 

 

/* setprecision(n) – устанавливает n значащих цифр после запятой с учетом точки или без нее, в зависимости от системы программирования. На экране:

1.56или 1.556 */ return 0;

}

169

Флажки

Помимо манипуляторов для управления выводом данных используются специальные флажки, принадлежащие классу ios, которые также позволяют формировать потоки вывода.

Установить флажок позволяет функция setiosflags(ios :: flag); Снять флажок позволяет функция resetiosflags(ios :: flag);

Причем можно установить сразу несколько флажков, используя для этого побитовую операцию «|» (поразрядное ИЛИ) для их объединения в одну группу.

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

флажками механизма вывода потоками.

 

 

И

#include<iostream.h>

 

 

 

 

Р

#include<iomanip.h>

 

 

 

 

#include<conio.h>

 

 

Г

 

void main(void) {

 

 

 

 

 

 

 

 

 

int a = 157;

 

 

 

 

 

cout<<setiosflags(ios :: showbase)<<a<<“ “<<oct<<a<<У“ “

 

 

 

 

 

<<hex<<a<< endl;

 

 

 

 

а

 

 

/* showbase – показать, в какой системе счисления выводится число. На

экране: 157

 

0235

0х9d */

 

Б

 

 

 

 

double a1 = 12.99, a2 = 15;

 

 

 

 

 

 

е

 

 

 

 

 

 

cout << setiosflags(ios :: showpoint | ios :: fixed)

/* showpoint

печатать деся ичнуюкточку,

fixed

выводить в форме с

фиксированной десятичной точкой */

 

 

 

 

 

<< setprecision(2) << setfill(‘*’) << setiosflags(ios :: right)

// right – выравнивать выв д по правому краю (по левому – left)

 

 

и

 

 

 

 

 

 

 

<< “ a1 т“ << setw(10) << a1

 

 

 

 

л

 

 

 

 

 

б

<<о“ a2 “ << setw(10) << a2 << endl;

 

 

*****12.99

a2 *****15.00

 

 

 

// На экране: a1

 

 

 

и

 

double pi = 3.14159;

 

 

 

 

 

cout << “ Pi “ << setw(15) << setfill(‘_’)

 

 

 

 

 

 

// С мвол заполнения ‘_’ – знак подчеркивания

 

 

 

<< setiosflags(ios :: showpos | ios :: scientific)

 

 

 

<< setprecision(5) << pi << endl;

 

 

 

Б/* showpos – явно показать знак «+», scientific – вывод в форме с плавающей

десятичной точкой. На экране: Pi _ _ _ +3.14159e+00

 

*/

}

 

 

 

 

 

 

 

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

170

16.3. Проблема ввода-вывода кириллицы в среде Visual C++

Работа в среде Visual C++ 6.0 (в режиме консольных приложений) сопряжена с определенными неудобствами. Например, попытка вывести фразу на русском языке, как стандартными функциями вывода, так и с помощью ввода-вывода потоками, терпит неудачу. Создадим в среде Visual C++ 6.0 консольное приложение и наберем следующий текст:

#include <iostream.h>

 

 

 

int main()

 

 

Р

{

 

 

cout << "Welcome to C++ !" << endl;

 

 

cout << "Добро пожаловать в C++ !" << endl;

 

 

return 0;

 

 

}

 

 

 

И

В результате на экране получим нечто следующее:

 

Welcome to C++ !

 

У

 

─юсЕю яюцрыютрЄ№ т C++ !

 

Г

 

 

Press any key to continue

 

 

То есть вместо фразы на русском языкеаполучаетсяБбессмысленный набор символов. Это вызвано различными ст нд ртами кодировки символов кириллицы в операционных системах MS DOS и Windows.

Весь ввод-вывод в консольном о не идет в кодировке стандарта ASCII.

Данный стандарт является международным только в первой половине кодов,

 

 

 

 

 

к

 

 

 

т.е. для кодов от 0 до 127, а вторая половина кодов от 128 до 255

предназначена для национальныхешрифтов. Так, например, в бывшем СССР

помимо альтернативной к дировки ГОСТа (Alt),

использовались – основная

кодировка ГОСТа (Mai), б лгарская кодировка

(MIC),

кодировка КОИ-8

 

 

 

 

т

 

 

 

 

(KOI), у которых с мв лы кириллицы имеют разные коды. Сейчас в России –

альтернативная код

ровка ASCII.

 

 

 

 

 

 

 

о

 

 

 

 

Текст же в сходных файлах, набираемый в текстовом редакторе Visual

 

и

 

 

 

 

 

C++, имеет кодировку в стандарте ANSI. Данный стандарт в первой половине

совпадает с альтернативной кодировкой ASCII, а во второй – отличается, так

и

л

 

 

 

 

 

 

 

Visual

решили,

что консольное приложение

должно

как разра отчики

Б

 

в среде MS DOS и оставили альтернативную кодировку

имит роватьботура

ASCII.

 

 

 

 

 

 

 

 

Для нормального

вывода

строки, содержащей

буквы

русского

алфавита, надо использовать функцию CharToOem, предназначенную для преобразования символов с кодировкой ANSI в кодировку ASCII. Аналогично, если в программе есть консольный ввод текста и этот текст в дальнейшем надо сохранять в документах (файлах) с кодировкой ANSI, то перед сохранением нужно воспользоваться функцией обратного преобразования – OemToChar. Эти функции декларированы в заголовочном файле windows.h.

171

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

#include <iostream.h>

 

 

 

 

 

 

 

 

 

 

#include <windows.h>

 

 

 

 

 

 

 

 

 

 

char* Rus(const char* text);

 

 

 

 

 

 

 

 

char bufRus[255];

 

 

 

 

 

 

 

 

 

 

int main()

 

 

 

 

 

 

 

 

 

 

 

 

{

 

 

 

 

 

 

 

 

 

 

 

 

char s[] = "Минск!", ss[100];

 

 

 

 

 

 

 

Р

cout << Rus("Город ") << Rus(s) <<endl;

 

 

 

cout << Rus("Введи строку:");

 

 

 

 

 

 

cin >> ss;

 

 

 

 

 

 

 

 

 

 

cout << Rus(" Строка: ") << ss << endl;

 

 

 

 

return 0;

 

 

 

 

 

 

 

 

 

И

}

 

 

 

 

 

 

 

 

 

 

char* Rus (const char* text)

 

 

 

 

 

 

 

 

 

 

 

 

 

У

 

{

 

 

 

 

 

 

 

 

 

 

CharToOem(text, bufRus);

 

 

 

Г

 

 

return bufRus;

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Б

 

 

 

}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Результат программы мож быть следующим:

 

 

 

Город Минск!

 

 

а

 

 

 

 

 

к

 

 

 

 

 

Введи строку: Москва!

 

 

 

 

 

Строка: Москва!

ет

 

проблемы

с

русским

языком в

Таким

образ

,

для

решения

 

 

ом

 

 

 

 

 

 

 

 

 

консольном выводе Visual C++ 6.0 создана небольшая функция Rus, которая

обращается

и

тCharToOem,

передает

ей

для преобразования

к функц

л

свой

параметр текст на русском языке и

возвращает

полученный

через

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

и

 

просто: везде вместо строковых объектов (строковых констант и

переменных) в программах нужно писать Rus(строковый объект).

Б

использование функции CharToOem, например, в

Непосредственноеб

стандартных функциях вывода данных недопустимо, так как возвращает результат типа BOOL, а результат преобразования размещает по адресу своего второго аргумента. Поэтому и была создана эта небольшая пользовательская функция, которая имеет единственное ограничение: функцию Rus нельзя использовать в цепочке операций << более одного раза, так как для различных компиляторов и режимов оптимизации может быть получен неверный результат.

172