Чтение онлайн

на главную

Жанры

Программирование. Принципы и практика использования 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

Теперь мы считали целую строку. Зачем нам это было нужно? Например, неплохой ответ: “Потому что мы сделали то, чего не может оператор

>>
”. Часто можно слышать совершенно неудачное объяснение: “Потому что пользователь набрал полную строку”. Если это все, что вы можете сказать, то используйте оператор
>>
, потому что, если вы ввели строку, то должны как-то ее разобрать на части.
Рассмотрим пример.

string first_name;

string second_name;

stringstream ss(name);

ss>>first_name; // ввод строки Dennis

ss>>second_name; // ввод строки Ritchie

Непосредственный ввод данных в строки

first_name
и
second_name
можно было бы выполнить проще. Одна из распространенных причин для считывания полной строки заключается в том, что определение разделителя не всегда является достаточно приемлемым. Иногда переход на новую строку желательно трактовать не как разделитель. Например, в ходе обмена сообщениями в компьютерной игре текст разумнее интерпретировать как предложение, не полагаясь на общепринятую пунктуацию.

идти налево, пока не увидишь картину справа на стене

сними картину со стены и открой дверь позади нее. Возьми сундук

В данном случае мы сначала прочитаем всю строку, а затем извлечем из нее отдельные слова.

string command;

getline(cin,command); // вводим строку

stringstream ss(command);

vector<string> words;

string s;

while (ss>>s) words.push_back(s); // извлекаем отдельные слова

С другой стороны, если есть выбор, то лучше всего ориентироваться на знаки пунктуации, а не на символ перехода на новую строку.

11.6. Классификация символов

Как правило, мы вводим целые числа, числа с плавающей точкой, слова и так далее, в соответствии с общепринятым форматом. Однако мы можем, а иногда и должны, снизить уровень абстракции и ввести отдельные символы. Для этого необходимо затратить больше усилий, но, считывая отдельные символы, мы получаем полный контроль на тем, что делаем. Рассмотрим задачу распознавания лексем в выражениях из раздела 7.8.2.

Допустим, мы хотим разделить выражение

1+4*x<=y/z*5
на одиннадцать лексем.

1 + 4 * x <= y / z * 5

Для ввода чисел мы могли бы использовать оператор

>>
, но, пытаясь ввести идентификаторы как строки, должны были бы прочитать фразу
x<=y
как целую строку (поскольку символы
<
и
=
не являются разделителями). Сочетание символов
z*
мы также должны были бы ввести как целую строку (поскольку символ
*
также не является разделителем).

Вместо этого можно сделать следующее:

char ch;

while (cin.get(ch)) {

if (isspace(ch)) { // если символ ch является разделителем,

// ничего не делаем (так как разделители

// игнорируются)

}

if (isdigit(ch)) {

// вводим число

}

else if (isalpha(ch)) {

// вводим идентификатор

Поделиться:
Популярные книги

Черный Маг Императора 13

Герда Александр
13. Черный маг императора
Фантастика:
попаданцы
аниме
сказочная фантастика
фэнтези
5.00
рейтинг книги
Черный Маг Императора 13

Последняя Арена 4

Греков Сергей
4. Последняя Арена
Фантастика:
рпг
постапокалипсис
5.00
рейтинг книги
Последняя Арена 4

Маяк надежды

Кас Маркус
5. Артефактор
Фантастика:
городское фэнтези
попаданцы
аниме
5.00
рейтинг книги
Маяк надежды

Великий перелом

Ланцов Михаил Алексеевич
2. Фрунзе
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Великий перелом

Сопротивляйся мне

Вечная Ольга
3. Порочная власть
Любовные романы:
современные любовные романы
эро литература
6.00
рейтинг книги
Сопротивляйся мне

Инквизитор Тьмы 2

Шмаков Алексей Семенович
2. Инквизитор Тьмы
Фантастика:
попаданцы
альтернативная история
аниме
5.00
рейтинг книги
Инквизитор Тьмы 2

Мастер Разума V

Кронос Александр
5. Мастер Разума
Фантастика:
городское фэнтези
попаданцы
5.00
рейтинг книги
Мастер Разума V

Бандит 2

Щепетнов Евгений Владимирович
2. Петр Синельников
Фантастика:
боевая фантастика
5.73
рейтинг книги
Бандит 2

Истребители. Трилогия

Поселягин Владимир Геннадьевич
Фантастика:
альтернативная история
7.30
рейтинг книги
Истребители. Трилогия

Гардемарин Ее Величества. Инкарнация

Уленгов Юрий
1. Гардемарин ее величества
Фантастика:
городское фэнтези
попаданцы
альтернативная история
аниме
фантастика: прочее
5.00
рейтинг книги
Гардемарин Ее Величества. Инкарнация

Падение Твердыни

Распопов Дмитрий Викторович
6. Венецианский купец
Фантастика:
попаданцы
альтернативная история
5.33
рейтинг книги
Падение Твердыни

"Дальние горизонты. Дух". Компиляция. Книги 1-25

Усманов Хайдарали
Собрание сочинений
Фантастика:
фэнтези
боевая фантастика
попаданцы
5.00
рейтинг книги
Дальние горизонты. Дух. Компиляция. Книги 1-25

Ох уж этот Мин Джин Хо 2

Кронос Александр
2. Мин Джин Хо
Фантастика:
попаданцы
5.00
рейтинг книги
Ох уж этот Мин Джин Хо 2

Энфис 6

Кронос Александр
6. Эрра
Фантастика:
героическая фантастика
рпг
аниме
5.00
рейтинг книги
Энфис 6