Основные теоретические сведения.




Лабораторная работа №1

Вывод в С++. Функции и манипуляторы cout.

 

Цель работы: познакомится со средой программирования DevC++, изучить основы написания простейших программ на С++, получить представление о выводе данных с использованием объекта cout.

 

Порядок выполнения работы.

1. Изучить теоретические сведения.

2. Выполнить задание 1: используя функции и манипуляторы объекта cout записать программу вывода на экран рисунка согласно своему варианту (см. таблицу 4). Заполняющий символ выбирается произвольно. Команды вывода должны содержать функции, флаги и манипуляторы объекта cout. Должен осуществляться вывод только заполняющего символа или пробела.

3. В процессе отладки разработанной программы зафиксировать все ошибки компиляции в виде таблицы 1. В таблице приведён пример оформления ошибок.

 

Таблица 1.

Пример ведения журнала ошибок

Ошибка/предупреждение Местоположение ошибки в программе Причина ошибки Исправление
error: expected initializer before 'n' Стр.6 кол.10 int mai n () ^ Ошибка в записи лексемы языка С++ int main ()

 

4. Исправить возможные логические ошибки в разработанном коде программы.

5. Получить исполняемый файл верно работающей программы (task1.exe).

6. Выполнить задание 2*: используя функции и манипуляторы объекта cout для работы с числами записать программу вывода на экран «рисунка» согласно своему варианту (см. таблицу 5).

7. В процессе отладки разработанной программы зафиксировать все ошибки компиляции в виде таблицы 1.

8. Получить исполняемый файл верно работающей программы (task2.exe).

9. Написать отчёт по проделанной работе.

10. Продемонстрировать работу программ task1.exe и task2.exe преподавателю.

 

Основные теоретические сведения.

Простейшая программа на С++.

// first.cpp – выводим сообщение на экран

#include <iostream> // директива препроцессора

using namespace std; // делает видимыми определения

 

int main() // заголовок функции

{ // начало тела функции

cout << "Hello, world!" << endl; // сообщение и новая строка

cin.get(); // задержка закрытия консоли

return 0; // завершение функции main()

} // конец тела функции

 

Потоки и буферы.

Программа на C++ воспринимает ввод и вывод как потоки байтов. При вводе программа извлекает байты из входного потока, а при выводе помещает байты в выходной поток. Для текстовых программ каждый байт может представлять символ. В общем случае байты могут образовывать двоичное представление символов и числовых данных. Байты входного потока могут поступать с клавиатуры, но также из устройств хранения, вроде жесткого диска, либо из другой программы. Аналогично, байты выходного потока могут передаваться на дисплей, на принтер, на устройство хранения или же отправляться другой программе. Потоки служат посредниками между программой и источником или местом назначения потока. Такой подход позволяет программам на C++ трактовать ввод с клавиатуры так же, как и ввод из файла; программа на C++ просто просматривает поток байтов, не нуждаясь в информации о том, откуда эти байты поступают. Точно так же, используя потоки, программа на C++ может обрабатывать вывод независимо от того, куда, собственно, направляются байты.

Практические детали передачи символов с устройства и на устройство находятся в компетенции библиотеки ввода-вывода и драйверов устройств.

Стандартная библиотека языка С++ содержит определение типа istream для потоков ввода и типа ostream – для потоков вывода. Чаще всего программах используются стандартный поток istream с именем cin и стандартный поток ostream с именем cout.

Поток ostream делает следующее:

- превращает значения разных типов в последовательности символов;

- посылает эти символы "куда-то" (например, на консоль, в файл, основную память или на другой компьютер).

Поток ostream можно представить следующим образом:

 

 

Буфер – это структура данных, которую поток ostream использует внутренне для хранения в ходе взаимодействия с операционной системой информации, полученной от вас. Задержка между записью в поток ostream и появлением символов в пункте назначения обычно объясняется тем, что эти символы находятся в буфере. Буферизация важна для производительности программы, а производительность программы важна при обработке больших объемов данных.

Поток istream делает следующее:

- превращает последовательности символов в значения разных типов;

- получает эти символы "откуда-то" (например, с консоли, из файла, из основной памяти или от другого компьютера).

Поток istream можно представить следующим образом:

 

 

Как и поток ostream. для взаимодействия с операционной системой поток istream использует буфер. При этом буферизация может оказаться визуально заметной для пользователя. Когда вы используете поток istream, связанный с клавиатурой, все, что вы введете, останется в буфере, пока вы не нажмёте клавишу <Enter> (возврат каретки/переход на новую строку). Так что если вы передумали, то, пока не нажали клавишу <Enter>. Можете стереть символы с помощью клавиши <Backspace>.

Одно из основных применений вывода – организация данных для чтения, доступного людям. Потоки ostream предоставляют много возможностей для форматирования текста по вкусу пользователей. Аналогично большая часть входной информации записывается людьми или форматируется так, чтобы люди могли ее прочитать. Потоки istream обеспечивают возможности для чтения данных, созданных потоками ostream.

 

Вывод с помощью cout.

Возможность управлять вводом-выводом в С++, обеспечивают форматирующие функции объектов ввода/вывода, флаги и манипуляторы. Они выполняют одну и туже задачу – задают определённый формат ввода/вывода информации в потоках. Различие между функциями, флагами и манипуляторами форматирования состоит в способе их применения.

 

а) Вывод с помощью перегруженной операции <<

Операция << объекта cout называется операцией вставки и является основной для вывода данных:

int clients = 22;

cout << clients;

Синтаксис операции:

cout << значение

Операция вставки перегружена для применения со всеми базовыми типами C++ и некоторым указателям:


unsigned char

signed char

char

short

unsigned short

int

unsigned int

long

unsigned long

long long

unsigned long long

float

double

long double

 

const signed char *

const unsigned char *

const char *

void *


Операции вставки в ostream преобразуют значения в текстовую форму. По умолчанию они форматируют значения следующим образом:

- значение типа char, если оно представляет печатаемый символ, отображается как символ в поле шириной в один символ;

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

- строки отображаются в поле ширины, равной длине строки;

- числа с плавающей точкой отображаются в поле общей шириной в шесть разрядов, за исключением завершающих нулей, которые не отображаются. (Следует отметить, что количество отображаемых разрядов никак не связано с точностью, с которой хранится число.) Число отображается либо в форме записи с фиксированной точкой, либо в экспоненциальной форме записи, в зависимости от значения числа. В частности, экспоненциальная запись используется, если порядок равен 6 или больше либо равен -5 или меньше. Опять-таки, ширина поля выбирается такой, чтобы вместить все цифры и знак минус, если он присутствует. Поведение по умолчанию соответствует использованию функции fprintf() из стандартной библиотеки С со спецификатором %g.

Функция операции вставки возвращает тот же объект, который вызвал операцию. Например, cout << "potluck" возвращает объект cout. Это свойство позволяет выполнять конкатенацию вывода, используя вставку.

Например, рассмотрим следующий оператор:

cout << "We have " << count << " unhatched chickens. \n";

Выражение cout << "We have " отображает строку и возвращает объект cout, сокращая оператор до следующего вида:

cout << count << " unhatched chickens.\n";

Затем выражение cout << count отображает значение переменной count и возвращает объект cout, который затем может использоваться для обработки заключительного аргумента в операторе.

 

б) Форматирование с помощью функций и флагов

Доступ к функциям объекта cout осуществляется через операцию точка, а в круглых скоках передаётся аргумент. Но одних функций не достаточно для форматирования потоков ввода/вывода, поэтому в С++ предусмотрен ещё один способ форматирования – флаги.

Например, код

cout.fill('*');

cout.width(5);

cout << "13" << endl;

выводит строку

***13

А код

cout.fill('*');

cout.unsetf(ios::dec);

cout.setf(ios::left | ios::oct);

cout.width(7);

cout << 100 << endl; // выводим число 100, а не строку "100"

выводит строку

144****

Основные форматирующие функции-члены:

- cout.fill(sym) – устанавливает символ заполнитель, где sym – символ-заполнитель, символ передаётся в одинарных кавычках в виде символа или в виде ascii-кода;

- cout.width(width_field) – задает ширину поля, width_field – количество позиций (одна позиция вмещает один символ);

- cout.precision(number) – задает количество знаков после десятичной точки, где number – количество знаков после десятичной точки.

Флаги форматирования (табл. 2) позволяют включить или выключить один из параметров ввода/вывода. Чтобы установить флаг ввода/вывода, необходимо вызвать функцию setf(). Метод setf() принимает один аргумент – имя флага. Флаги вывода объявлены в классе ios, поэтому, перед тем, как обратиться к флагу, необходимо написать имя класса – ios, после которого, с помощью операции разрешения области действия, вызвать нужный флаг:

cout.setf(ios::/*name_flag*/); // где name_flag – это имя флага

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

cout.unsetf(ios::/*name_flag*/); // где name_flag – это имя флага

Если при вводе/выводе необходимо установить(снять) несколько флагов, то можно воспользоваться поразрядной логической операцией ИЛИ |. В этом случае конструкция языка C++ будет такой:

// установка нескольких флагов

cout.setf(ios::/*flag1*/ | ios::/*flag2*/ | ios::/*flag_n*/);

 

// снятие нескольких флагов

cout.unsetf(ios::/*flag1*/ | ios::/*flag2*/ | ios::/*flag_n*/);

 

Таблица 2.

Основные флаги форматирования С++

Флаг Назначение Пример Результат
boolalpha Вывод логических величин в текстовом виде (true, false) cout.setf(ios::boolalpha); bool log_false = 0, log_true = 1; cout << log_false << endl << log_true << endl; false true
oct Ввод/вывод величин в восьмеричной системе счисления (сначала снимаем флаг dec, затем устанавливаем флаг oct) cout.unsetf(ios::dec); cout.setf(ios::oct); int value; cin >> value; cout << value << endl; ввод:9910 вывод:1438
dec Ввод/вывод величин в десятичной системе счисления (флаг установлен по умолчанию) cout.setf(ios::dec); int value = 148; cout << value << endl;  
hex Ввод/вывод величин в шестнадцатеричной системе счисления (сначала снимаем флаг dec, затем устанавливаем флаг hex) cout.unsetf(ios::dec); cout.setf(ios::hex); int value; cin >> value; cout << value << endl; ввод:9910 вывод:6316
showbase Выводить индикатор основания системы счисления cout.unsetf(ios::dec); cout.setf(ios::oct | ios::showbase); int value; cin >> value; cout << value << endl; ввод:9910 вывод:01438
uppercase В шестнадцатеричной системе счисления использовать буквы верхнего регистра (по умолчанию установлены буквы нижнего регистра) cout.unsetf(ios::dec); cout.setf(ios::hex | ios::uppercase); int value; cin >> value; cout << value << endl; ввод:25510 вывод:FF16
showpos Вывод знака плюс + для положительных чисел cout.setf(ios::showpos); int value = 15; cout << value << endl; +15
scientific Вывод чисел с плавающей точкой в экспоненциальной форме cout.setf(ios::scientific); double value = 1024.165; cout << value << endl; 1.024165e+003
fixed Вывод чисел с плавающей точкой в фиксированной форме (по умолчанию) double value = 1024.165; cout << value << endl; 1024.165
right Выравнивание по правой границе (по умолчанию). Сначала необходимо установить ширину поля, заведомо большую чем, длина выводимой строки. cout.width(10); cout << «Hello» << endl; _____Hello
left Выравнивание по левой границе. Сначала необходимо установить ширину поля, заведомо большую чем, длина выводимой строки. cout.setf(ios::left); cout.width(10); cout << «Hello» << endl; Hello_____

 

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

Код

cout << "Hello, " << endl << "world!";

выводит текст в двух строках

Hello,

world!

Специальные обозначения наподобие endl, которые имеют определенное значение для cout, называются манипуляторами. Как и cout, манипулятор endl определен в заголовочном файле iostream и является частью пространства имен std.

Манипуляторы стандартной библиотеки приведены в таблице 3. Стандартные манипуляторы определены в заголовочных файлах <ios>. <istream>, <ostream>, <iostream> и <iomanip> (для манипуляторов, получающих аргументы).

 

Таблица 3.

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

Манипуляторы вывода
boolalpha Использовать символьное представление значений true и false (ввод и вывод)
noboolalpha cout.unsetf (ios_base::boolalpha)
showbase Показывать префиксы вывода oct в виде О и hex в виде Ох
noshowbase cout.unsetf (ios_base::showbase)
showpoint Всегда показывать десятичную точку
noshowpoint cout.unsetf (ios_base::showpoint)
showpos Показывать символ + перед положительными числами
noshowpos cout.unsetf (ios_base::showpos)
uppercase Использовать верхний регистр при выводе чисел, например 1.2Е10 и ОХ1А2, а не 1.2е10 и Oxla2
nouppercase Выводить х и е, а не х и Е
left Вставлять пробелы после значения
right Вставлять пробелы перед значением
dec Основание счисления равно 10
hex Основание счисления равно 16
oct Основание счисления равно 8
fixed Формат чисел с плавающей точкой dddd.dd
scientific Научный формат d.dddd.Edd
defaultfloat Формат, дающий наиболее точный вывод значений с плавающей точкой
endl Вставить '\n' и сбросить буфер. Начало новой строки.
resetiosflags(f) Сбросить флаги f
setiosflags(f) Установить флаги f
setbase(b) Выводить целые числа по основанию b (в <iomanip>)
setfill(с) Сделать символ с символом заполнения (в <iomanip>)
setprecision(n) Точность равна n цифр (в <iomanip>)
setw(n) Ширина следующего поля равна n символам (в <iomanip>)
Манипуляторы ввода
skipws Пропускать пробелы
noskipws cout.unsetf (ios_base::skipws)
ws Удалить разделители

 

Пример 1. Код

cout << 1234 << ", " << hex << 1234 << ", " << oct << 1234 << endl;

выводит на экран следующую строку:

1234, 4d2, 2322

Пример 2. Код

cout <<" ("<<setw(4)<<setfill("#")<<12<< ") (" << 12 << ") \n";

выводит на экран строку

(##12) (12)

Пример 3. Код

float n = 0.1/0.9+1;

cout << setw(4) << '1' << endl;

cout.precision(2);

cout << setw(5) << right << n << endl;

cout.precision(4);

cout << setw(6) << right << n*10 << endl;

выведет на экран «пирамиду»

1.1

11.11

 

 

Содержание отчёта.

1. Титульный лист.

2. Цель работы.

3. Индивидуальное задание 1.

4. Первоначальный код решения задания 1.

5. Журнал ошибок компиляции (отладочная таблица 1) программного кода, приведённого в предыдущем пункте.

6. Исправленный исходный код решения задания 1

7. Результат работы программы предыдущего пункта.

8. П. 3-7 для задания 2*.

9. Выводы по проделанной работе.

 

Таблица 4.

Индивидуальное задание 1.

Вариант «Рисунок» Вариант «Рисунок»
1. 2.
3. 4.
5. 6.
7. 8.
9. 10.
11. 12.
13. 14.
15. 16.

 

Таблица 5.

Индивидуальное задание 2 (дополнительное задание).

Четные варианты 3.3 33.3 333.3 33.3 3.3 Вывод чисел 3 и (1/3+3)*n, где n – целое положительное число с использованием манипуляторов cout для чисел с плавающей запятой.
Нечётные варианты 6.666 6.66 6.6 6.6 66.6 666.6 Вывод чисел 6 и (2/3+6)*n, где n – целое положительное число с использованием манипуляторов cout для чисел с плавающей запятой.

 

 



Поделиться:




Поиск по сайту

©2015-2024 poisk-ru.ru
Все права принадлежать их авторам. Данный сайт не претендует на авторства, а предоставляет бесплатное использование.
Дата создания страницы: 2019-09-20 Нарушение авторских прав и Нарушение персональных данных


Поиск по сайту: