Программирование. Принципы и практика использования C++ Исправленное издание
Шрифт:
Эти
fstream fs(name.c_str); // открыть для ввода и вывода
if (!fs) error("Невозможно открыть файл ",name);
fs.seekg(5); // перенести позицию считывания (буква g означает "get")
// на пять ячеек вперед (шестой символ)
char ch;
fs>>ch; // считать и увеличить номер позиции для считывания
cout << " шестой символ — это " << ch << '(' << int(ch) << ")\n";
fs.seekp(1); // перенести позицию для записи (буква p означает "put")
// на одну ячейку вперед
fs<<'y'; // записать и увеличить позицию для записи
Будьте осторожны: ошибки позиционирования не распознаются. В частности, если вы попытаетесь выйти за пределы файла (используя функцию
seekg
или seekp
), то последствия могут быть непредсказуемыми и состояние операционной системы изменится. 11.4. Потоки строк
istream
или цели вывода для потока ostream
можно использовать объект класса string
. Поток istream
, считывающий данные из объекта класса string
, называется istringstream
, а поток ostream
, записывающий символы в объект класса string
, называется ostringstream
. Например, поток istringstream
полезен для извлечения числовых значений из строк.
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 содержит также средства для ввода отдельных символов и целых строк. Рассмотрим пример.
Поделиться с друзьями: