Потоковый ввод-вывод С++
.pdfvk.com/club152685050
Потоковый ввод-вывод
В Си++ существует стандартная библиотека классов, ориентированная на организацию потокового ввода-вывода.
ios_base
ios
istream ostream
Base class for streams
Base class for streams (type-dependent components) typedef basic_ios<char> ios;
Base class for all stream classes using narrow characters (of type char)
iostream
Иерархия классов библиотеки ввода-вывода
Классы ввода-вывода образуют иерархию по принципу наследования (на каждом следующем уровне иерархии в класс добавляются новые свойства и методы). Базовым в этой иерархии является класс ios (исключение составляют лишь классы буферизированных потоков). В классе ios объединены базовые данные и методы для ввода-вывода. Прямыми потомками класса ios являются классы istream и ostream.
istream – это класс входных потоков; ostream – класс выходных потоков;
iostream – класс двунаправленных потоков ввода-вывода.
Потоковые классы, их свойства и методы (данные и функции) становятся видимыми и доступными в программе при подключении заголовочного файла
#include “iostream.h” (в новом стандатре языка С++ расширение h у некоторых заголовочных файлов убрано)
или библиотеки
#include <iostream>
Библиотека iostream не только подключает к программе описания классов ios, istream, ostream, iostream, но и содержит определения стандартных потоков ввода-вывода: cin - объект класса istream, связанный со стандартным буферизированным входным потоком (обычно клавиатура консоли); потоком ввода, связанным с клавиатурой
cout - объект класса ostream, связанный со стандартным буферизированным выходным потоком (обычно дисплей консоли); поток вывода, связанный с дисплеем
cerr - объект класса ostream, связанный со стандартным небуферизированным выходным потоком (обычно дисплей консоли), в который направляются сообщения об ошибках; clog - объект класса ostream, связанный со стандартным буферизированным выходным потоком (обычно дисплей консоли), в который с буферизацией направляются сообщения об ошибках.
vk.com/club152685050
Каждый раз при включении в программу файла iostream.h происходит формирование объектов cin, cout, cerr, clog, т.е. создаются соответствующие стандартные потоки, и программисту становятся доступными связанные с ними средства ввода-вывода.
Для потоков определены оригинальные операции ввода и вывода данных.
Операция ввода класса istream называется извлечением (чтением) данных из потока. Она обозначается с помощью символа операции сдвига вправо >>.
Операция вывода класса ostream называется вставкой или включением (или записью) данных в поток. Она обозначается с помощью символа операции сдвига влево <<.
Эти операции определены путем перегрузки операций сдвига.
Конструкции >> и << играют роль операции извлечения и вставки по умолчанию только в том случае, если слева от них находятся объекты, соответственно, классов istream и ostream:
cin >> имя_объекта_базового_типа cout << выражение_базового_типа cerr << выражение_базового_типа clog << выражение_базового_типа
Впротивном случае они как обычно обозначают операции сдвига.
Всоответствии с синтаксисом языка операции сдвига << и >> имеют невысокий приоритет. Им "предшествуют", например, все арифметические oпeрации, преобразования типов, скобки и др. Использование операций << и >> для обозначения передач данных в потоки и из потоков не изменяет их приоритета.
Эти операции определены путем перегрузки операций сдвига.
Приоритет << достаточно низкий, чтобы писать арифметические выражения в качестве операнда без скобок:
int a=4, b=3, c=2;
cout << "a*b+c=" << a*b+c; // 14
Если выражение содержит операции с более низким приоритетом, требуется применение скобок
cout << (а + b < с) ;
Операцию сдвига влево/вправо можно использовать в операции вывода, но,
конечно, она должна быть в скобках:
cout << "a<<b=" << (a<<b) << '\n';
vk.com/club152685050
Выполнение операции >> (извлечение из потока) заключается в преобразовании последовательности символов потока в значение типизированного объекта, частным случаем которого является переменная базового типа int, long, double и т.д. При выполнении операции << (включение в поток) осуществляется обратное преобразование - типизированное значение выражения (int, float, char и т.д.) трансформируется в последовательность символов потока.
Величины при вводе должны разделяться пробельными символами (пробелами, знаками табуляции или перевода строки).
Извлечение прекращается, если очередной символ оказался недопустимым.
int a,b; cout<<"Введите a, b: "; cin>>a>>b;
cout<<"Вы ввели: "<<a<<" "<<b<<endl;
Операции << и >> перегружены для всех встроенных типов данных, что позволяет автоматически выполнять ввод и вывод в соответствии с типом величин. Это означает, что при вводе последовательность символов преобразуется во внутреннее представление величины, стоящей справа от знака извлечения, а при выводе выполняется обратное преобразование.
Числовые значения можно вводить в десятичной, восьмеричной, шестнадцатеричной системе счисления. Вещественные числа представляются в форме с фиксированной точкой или порядком.
При вводе строк извлечение происходит до ближайшего пробела.
Одно значение – до enter
При необходимости ввести из входного потока строку целиком (до символа ‘\n’) пользуются методами get и getline
Значения указателей выводятся в шестнадцатеричной системе счисления Значения типа char всегда выводятся как символьные. Для получения кода символа требуется явное приведение типа
char c=65;
cout<<"char как символ "<<c<<endl; // на экране появится символ А cout<<"char как число "<<(int)c<<endl; // на экране появится число 65
Результат работы программы char как символ A
char как число 65
Для организации форматированного потокового ввода-вывода в Си++ существуют два средства:
- применение функций-членов класса ios для управления флагами форматирования; -применение функций-манипуляторов.
1) флаги форматирования и функции
Флаги форматирования
Флаги форматирования – двоичные коды, управляющие форматом выводимых значений.
vk.com/club152685050
Флаги представляют собой отдельные биты, объединенные в поле x_flags типа long класса
ios. В заголовочном файле iostream.h определено следующее перечисление, задающее флаги форматирования:
enum {
skipws= |
0x0001, // при извлечении пробельные символы игнорируются |
|
left= |
0x0002, // выравнивание по левому краю поля |
|
right= |
0x0004, // выравнивание по правому краю поля |
|
internal= |
0x0008, |
// добавление символов между знаком и значением |
dec= |
|
// основание целого: |
0x0010, // вывод в десятичном виде |
||
oct= |
0x0020, // вывод в восьмеричном виде |
|
hex= |
0x0040, // вывод в шестнадцатеричном виде |
|
showbase= |
0x0080, //показать основание системы счисления (0, 0x) |
|
showpoint= |
0x0100, // выдача позиции точки |
|
uppercase= |
0x0200, // при выводе использовать символы верхнего |
|
showpos= |
0x0400, |
регистра ('E', 'X' , а не 'e', 'x') |
// '+' для положительных чисел |
||
scientific= |
0x0800, |
// запись числа типа float: |
// d.dd Edd |
||
fixed= |
0x1000, //вывод в форме с фиксированной точкой dddd.dd |
|
unitbuf= |
0x2000, |
// сброс в выходной поток: |
// после каждой операции |
||
stdio= |
0x4000 |
// после каждого символа |
}; Фактически в этом списке содержатся имена констант, определяющие флаги
соответствующих назначений. Коду формата соответствует целый тип long.
Флаги вывода объявлены в классе ios, поэтому, перед тем, как обратиться к флагу, необходимо написать имя класса - ios, после которого, с помощью операции разрешения области действия, вызвать нужный флаг. Например: ios::hex
Изменить состояние флагов формата можно с помощью функции long setf(long flags)
Для отключения используется функция unsetf(long flags);
Далее показаны конструкции установки и снятия флагов вывода.
//установка флага вывода cout.setf( ios::/*name_flag*/ );
//где name_flag - это имя флага
//снятие флага вывода cout.unsetf( ios::/*name_flag*/ );
//где name_flag - это имя флага
long flags () - возвращает текущее состояние флагов;
long flags (long f) - присваивает флагам значение параметра;
Некоторые другие функции-члены класса ios:
int width(int w); |
// |
задает ширину поля вывода равную |
w. Если ширина |
|||
задана |
меньше, |
чем количество символов, все равно |
они все будут напечатаны |
|||
char fill(char |
ch); |
// |
устанавливает символ заполнитель |
ch |
||
// где |
ch - символ заполнитель, символ передаётся |
в одинарных кавычках |
vk.com/club152685050
int precision(int num); // задает количество знаков после десятичной точки // где num - количество знаков после десятичной точки
double x=521.3789; cout.width(10); cout.fill('#'); cout.precision(2); cout.setf(ios::fixed); cout <<x<<endl; cout.unsetf(ios::fixed); cout <<x<<endl;
long n=254; cout.unsetf(ios::dec);
cout.setf( ios::hex|ios::showbase|ios::uppercase); cout <<n<<endl;
Результат:
####521.38
5.2e+002
254 = 0XFE
Вызов width, fill влияет только на одну следующую за ними операцию вывода
По умолчанию поле заполняется пробелами, а размер поля по умолчанию есть 0, что означает "столько символов, сколько нужно". Вернуть размеру поля стандартное значение можно с помощью вызова
cout.width(0); // ``столько символов, сколько надо''
Функция width() задает минимальное число символов. Если ширина задана меньше, чем количество символов, все равно они все будут напечатаны
Использование манипуляторов. Для управления форматами потокового вывода можно использовать специальные функции, называемые манипуляторами.
Манипулятор — объект особого типа, который управляет потоками ввода/вывода, для форматирования передаваемой в потоки информации. Отчасти манипуляторы дополняют функционал, для форматирования ввода/вывода. Но большинство манипуляторов выполняют точно, то же самое, что и функции с флагами форматирования. Есть случаи, когда проще пользоваться флагами или функциямиформатирования, а иногда удобнее использовать манипуляторы форматирования. Именно по этому в С++ предусмотрено несколько средств форматирования ввода/вывода.
В таблице показаны основные манипуляторы форматирования С++.
endl |
Переход на новую строку при |
|
|
выводе |
|
ends |
Вывод нулевого символа NULL |
|
boolalpha |
Вывод логических величин в |
bool log_true = 1; |
|
текстовом виде (true, false) |
cout<< boolalpha << log_true << endl; |
|
|
true |
noboolalpha |
Вывод логических величин в |
|
|
числовом виде |
|
oct |
Вывод величин в восьмеричной |
int value = 64; |
|
системе счисления |
cout << oct << value << endl; // 1008 |
dec |
Вывод величин в десятичной |
int value = 0xff; |
|
системе счисления (по |
cout << dec << value << endl; |
|
умолчанию) |
25510 |
vk.com/club152685050
hex |
Вывод величин в |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int value = 64; |
|||||||||||||||||||||||||||||
|
шестнадцатеричной системе |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
cout << hex << value << endl; |
||||||||||||||||||||||||||||
|
счисления |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
40 |
|
|
|
|
|
|
|
|
|
|
|
|
|
||||||||||||||||
|
|
8 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||||||||
showbase |
Выводить индикатор основания |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||||
|
int value = 64; |
|||||||||||||||||||||||||||||
|
системы счисления |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|||||
|
|
cout<<showbase<<hex << value << endl; |
||||||||||||||||||||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||
|
|
0×40 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||||||||||||||
noshowbase |
Не выводить индикатор |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||||||
|
int value = 64; |
|||||||||||||||||||||||||||||
|
основания системы счисления |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|||||||
|
|
cout<<noshowbase<<hex<<value<<endl; |
||||||||||||||||||||||||||||
|
(по умолчанию). |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
40 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|||||
uppercase |
В шестнадцатеричной системе |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|||||||||
|
int value = 255; |
|||||||||||||||||||||||||||||
|
счисления использовать буквы |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||||||||||
|
|
cout<<uppercase<<hex << value << endl; |
||||||||||||||||||||||||||||
|
верхнего регистра |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|||||||||||
|
|
FF |
16 |
|||||||||||||||||||||||||||
nouppercase |
В шестнадцатеричной системе |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|||||||||||||
|
int value = 255; |
|||||||||||||||||||||||||||||
|
счисления использовать буквы |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||||||||||||||
|
|
cout<<nouppercase<<hex<<value<< endl; |
||||||||||||||||||||||||||||
|
нижнего регистра (по |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|||||||||||||||
|
|
ff |
16 |
|||||||||||||||||||||||||||
|
умолчанию). |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
showpos |
Вывод знака плюс+ для |
|
|
|
|
|
|
|
|
|
|
|
||||||||||||||||||
|
int value = 255; |
|||||||||||||||||||||||||||||
|
положительных чисел |
|
|
|
|
|
|
|
|
|
|
|||||||||||||||||||
|
|
cout << showpos<< value << endl; |
||||||||||||||||||||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||||||||||
|
|
+255 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||||||||||||||
noshowpos |
Не выводить знак плюс+ для |
|
|
|
|
|
|
|
|
|
||||||||||||||||||||
|
int value = 255; |
|||||||||||||||||||||||||||||
|
положительных чисел (по |
|
|
|
|
|
|
|
|
|
||||||||||||||||||||
|
|
cout << showpos<< value << endl; |
||||||||||||||||||||||||||||
|
умолчанию) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||||||||
|
255 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|||||||||||
scientific |
Вывод чисел с плавающей |
|
|
|
|
|
|
|
||||||||||||||||||||||
|
double value = 1024.165; |
|||||||||||||||||||||||||||||
|
точкой в экспоненциальной |
|
|
|
|
|
|
|||||||||||||||||||||||
|
|
cout << scientific << value << endl; |
||||||||||||||||||||||||||||
|
форме |
|
|
|
|
|
||||||||||||||||||||||||
|
|
1.024165e+003 |
||||||||||||||||||||||||||||
fixed |
Вывод чисел с плавающей |
|
|
|
|
|
||||||||||||||||||||||||
|
double value = 1024.165; |
|||||||||||||||||||||||||||||
|
точкой в фиксированной форме |
|
|
|
|
|||||||||||||||||||||||||
|
|
cout << fixed << value << endl; |
||||||||||||||||||||||||||||
|
(по умолчанию) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||||||||||||
|
1024.165 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|||||||||||||||
setw(int |
Установить ширину поля, |
|
Манипулятор с параметром.cout << |
|||||||||||||||||||||||||||
number) |
где number - количество |
|
setw(40) << «cppstudio.com» << |
|||||||||||||||||||||||||||
|
позиций, символов |
|
endl;__cppstudio.com |
|||||||||||||||||||||||||||
|
(выравнивание по умолчанию |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
по правой границе) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
right |
Выравнивание по правой |
|
cout << setw(40) << right << |
|||||||||||||||||||||||||||
|
границе(по умолчанию). |
|
«cppstudio.com» << endl; |
|||||||||||||||||||||||||||
|
Сначала необходимо установить |
|
__cppstudio.com |
|||||||||||||||||||||||||||
|
ширину поля(ширина поля |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
должна быть заведомо большей |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
чем, длинна выводимой строки) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
left |
Выравнивание по левой |
|
cout << setw(40) << left << |
|||||||||||||||||||||||||||
|
границе. Сначала необходимо |
|
«cppstudio.com» << endl; |
|||||||||||||||||||||||||||
|
установить ширину |
|
cppstudio.com__ |
|||||||||||||||||||||||||||
|
поля(ширина поля должна быть |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
заведомо большей чем, длинна |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
выводимой строки) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
setprecision |
Задаёт количество знаков после |
|
cout<<fixed<<setprecision(3) << (13.5 / 2) |
|||||||||||||||||||||||||||
(int count) |
запятой, где count - количество |
|
<< endl; |
|||||||||||||||||||||||||||
|
знаков после десятичной точки |
6.750 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vk.com/club152685050
Setfill |
Установить символ |
(int symbol) |
заполнитель. Если ширина поля |
|
больше, чем выводимая |
|
величина, то свободные места |
|
поля будут наполняться |
|
символом symbol - символ |
|
заполнитель |
cout << setfill(’0′) << setw(4) << 15 << ends << endl;
0015
.