Шрифт:
double str_to_double(string s)
// если это возможно, преобразовывает символы из строки s
// в число с плавающей точкой
{
istringstream is(s); // создаем поток для ввода из строки s
double d;
is >> d;
if (!is) error("Ошибка форматирования типа double: ",s);
return d;
}
double d1 = str_to_double("12.4"); // проверка
double d2 = str_to_double("1.34e–3");
double d3 = str_to_double("twelve point three"); // вызывается
// error
Если попытаться прочитать данные за пределами строки, предназначенной для ввода в поток
istringstream
, то он перейдет в состояние eof
. Это значит, что для потока istringstream
можно использовать обычный цикл ввода; поток istringstream
на самом деле является разновидностью потока istream
. Поток
ostringstream
, наоборот, может быть полезен для форматирования вывода в системах, ожидающих аргумента в виде простой строки, например в системах графического пользовательского интерфейса (раздел 16.5). Рассмотрим пример.
void my_code(string label, Temperature temp)
{
// ...
ostringstream os; // поток для составления сообщения
os << setw(8) << label << ": "
<< fixed << setprecision(5) << temp.temp << temp.unit;
someobject.display(Point(100,100), os.str.c_str);
// ...
}
Функция-член
str
класса ostringstream
возвращает объект класса string
, составленный операторами вывода, в поток ostringstream
. Функция c_str
— это функция-член класса string
, возвращающая строки в стиле языка C, которые ожидаются интерфейсами многих систем.
stringstream
обычно используются, когда мы хотим отделить собственно ввод-вывод от обработки данных. Например, аргумент типа string
в функции str_to_double
обычно поступает из файла (например, из журнала событий веб) или с клавиатуры. Аналогично, сообщение, составленное функцией my_code
, в конце концов выводится на экран. Например, в разделе 11.7 мы используем поток stringstream
при выводе для фильтрации нежелательных символов. Таким образом, потоки stringstream
можно интерпретировать как механизм настройки ввода-вывода для особых потребностей и вкусов. Продемонстрируем использование потока
ostringstream
на простом примере конкатенации строк.
int seq_no = get_next_number; // вводим число из системного журнала
ostringstream name;
name << "myfile" << seq_no; // например, myfile17
ofstream logfile(name.str.c_str); // например, открыть myfile17
Как правило, поток
istringstream
инициализируется объектом класса string
, а затем считывает из него символы, используя операторы ввода. И наоборот, поток ostringstream
инициализируется пустым объектом класса string
, а затем заполняется с помощью операторов вывода. Существует более простой способ доступа к символам в потоке stringstream
, который иногда оказывается полезным: функция ss.str
возвращает копию строки из объекта ss
, а функция ss.str(s)
присваивает строке в объекте ss
копию строки s
. В разделе 11.7 приведен пример, в котором функция ss.str(s)
играет существенную роль. 11.5. Ввод, ориентированный на строки
Оператор
>>
вводит данные в объекты заданного типа в соответствии со стандартным форматом, установленным для этого типа. Например, при вводе чисел в объект типа int
оператор >>
будет выполнять ввод, пока не обнаружит символ, не являющийся цифрой, а при вводе в объект класса string
оператор >>
будет считывать символы, пока не обнаружит разделитель (whitespace). Стандартная библиотека istream содержит также средства для ввода отдельных символов и целых строк. Рассмотрим пример.
string name;
cin >> name; // ввод: Dennis Ritchie
cout << name << '\n'; // вывод: Dennis
Что, если мы захотим прочитать всю строку сразу, а способ ее форматирования выберем потом? Это можно сделать с помощью функции
getline
. Рассмотрим пример.
string name;
getline(cin,name); // ввод: Dennis Ritchie
cout << name << '\n'; // вывод: Dennis Ritchie