================
0x123abc
0x123abc
0x 123abc
================
0123456
0123456
0123456
A hex number with upper case letters: 0X123ABC
A number: 0X64
Oops. now in decimal again: 100
true/false values: 1, 0
true/false values: true, false
doubles: 12.3, 12, 12.0000
scientific double: 1.230000E+11
fixed double: 123000000000.123001
Very precise double: 0.0000000001
Less precise double: 0.0
Как это работает
Все эти stream выражения, << foo << bar
input_stream >> modifier
или output_stream << modifier
, в этом случае они будут влиять на входные или выходные данные.Самый лучший способ познакомиться с этими модификаторами — изучить все их многообразие и немного поработать с ними.
При взаимодействии, однако, мы уже могли заметить, что большинство модификаторов являются
setw
и quoted
. Они влияют только на следующий элемент входных/выходных данных. Это важно знать, поскольку при выводе неких данных с определенным форматированием нужно сбрасывать настройки форматирования объекта потока, так как следующий блок выходных данных, создаваемый несвязанным кодом, может выглядеть странно. Это же верно и для преобразования входных данных, где правильный ход программы может быть нарушен из-за неверных настроек манипулятора ввода/вывода.Мы не использовали следующие манипуляторы, поскольку они никак не связаны с форматированием, но для полноты картины рассмотрим и их (табл. 7.2).
Среди перечисленных модификаторов стойкими являются только skipws/noskipws
unitbuf/nounitbuf
.Инициализируем сложные объекты из файла вывода
Считывать отдельные числа и слова довольно просто, поскольку оператор >>
Но что, если перед нами более сложная структура и нужно прочесть ее из потока ввода или же требуется считать строки, состоящие более чем из одного слова (по умолчанию они будут разбиты на отдельные слова из-за того, что пробелы опускаются)?
Для любого типа можно предоставить еще одну перегруженную версию оператора потока ввода >>
Как это делается
В этом примере мы определим пользовательскую структуру данных и предоставим возможности для чтения ее объектов из потоков ввода.
1. Включим некоторые заголовочные файлы и объявим об использовании пространства имен std
#include
#include
#include
#include
#include
#include
using namespace std;
2. В качестве примера сложного объекта определим структуру city
struct city {
string name;
size_t population;
double latitude;
double longitude;
};
3. Чтобы считать объект такой структуры из последовательного потока ввода, следует перегрузить оператор потоковой функции >>
ws
, поскольку пробелы не должны засорять название города. Затем считаем целую строку текста. Это подразумевает, что входной файл будет включать строку, в которой записано только название города. Затем, после символа новой строки, будет следовать список чисел, разделенный запятой, в котором содержится информация о численности населения, а также географическая широта и долгота:istream& operator>>(istream &is, city &c)
{
is >> ws; getline(is, c.name);
is >> c.population
>> c.latitude
>> c.longitude; return is;
}
4. В нашей функции main
city
. Заполним его с помощью std::copy
. Входными данными для вызова copy является диапазон istream_iterator
. Передавая ему тип структуры city
в качестве параметра шаблона, мы будем использовать перегруженную функцию >>
, реализованную только что: