- Фантастика и фэнтези
- Ироническое фэнтези
- Стимпанк
- Детективная фантастика
- Киберпанк
- Попаданцы
- LitRPG
- Космоопера
- Технофэнтези
- Городская фантастика
- Русское фэнтези
- Юмористическая фантастика
- Космическая фантастика
- Боевое фэнтези
- Эпическая фантастика
- Зарубежная фантастика
- Книги магов
- Мистика
- Разная фантастика
- Разное фэнтези
- Любовное фэнтези
- Романтическая фантастика
- Городское фентези
- Историческая фантастика
- Историческое фэнтези
- Социально-философская фантастика
- Сказочная фантастика
- Иностранное фэнтези
- Романтическое фэнтези
- Ироническая фантастика
- Ужасы и Мистика
- Постапокалипсис
- Героическая фантастика
- Фэнтези
- Научная Фантастика
- Социально-психологическая
- Альтернативная история
- Боевая фантастика
- Разная литература
- Пословицы, поговорки
- Шахматы
- Визуальные искусства
- Фанфик
- Авто и ПДД
- Военное
- Отраслевые издания
- Гиды, путеводители
- Зарубежная образовательная литература
- Военная история
- Цитаты из афоризмов
- Современная литература
- Великолепные истории
- Начинающие авторы
- Современная зарубежная литература
- Боевые искусства
- Изобразительное искусство, фотография
- Кино
- Литература 19 века
- Недвижимость
- Музыка, музыканты
- Готические новеллы
- Истории из жизни
- Культура и искусство
- Спецслужбы
- Зарубежная прикладная литература
- Музыка, танцы
- Подростковая литература
- Прочее
- Военная техника, оружие
- Газеты и журналы
- Периодические издания
- Домоводство, Дом и семья
- Любовные романы
- Экономическая литература
- Научные и научно-популярные книги
- О животных
- Биохимия
- Культурология
- Юриспруденция
- Политика
- Психотерапия
- Языкознание
- Научпоп
- Медицина
- Психология, личное
- Радиотехника
- Филология
- Педагогика
- Образовательная литература
- Деловая литература
- Физика
- Науки: разное
- Химия
- Воспитание детей, педагогика
- Детская психология
- Зарубежная публицистика
- Биология
- Архитектура
- Зарубежная психология
- Науки о космосе
- Социология
- Математика
- География
- Беременность, ожидание детей
- Литературоведение
- Транспорт, военная техника
- Обществознание
- Зоология
- География
- Альтернативная медицина
- Иностранные языки
- Ветеринария
- Рефераты
- Астрология
- Биофизика
- Экология
- История Европы
- Учебники
- Шпаргалки
- Государство и право
- Ботаника
- Религиоведение
- История
- Техническая литература
- Прочая научная литература
- Психология
- Детективы и Триллеры
- Справочная литература
- Проза
- Новелла
- Юмор
- Проза
- Историческая проза
- Русская современная проза
- Советская классическая проза
- Повести
- Очерки
- Эссе
- Рассказы
- Зарубежная современная проза
- Сентиментальная проза
- Зарубежная классика
- Афоризмы
- Эпистолярная проза
- Феерия
- Семейный роман/Семейная сага
- Разное
- Антисоветская литература
- Магический реализм
- Русская классическая проза
- Современная проза
- О войне
- Контркультура
- Классическая проза
- Поэзия, Драматургия
- Детская литература
- Детская фантастика
- Детские остросюжетные
- Детские стихи
- Детские приключения
- Внеклассное чтение
- Учебная литература
- Зарубежные детские книги
- Бизнес
- Загадки
- Книги для подростков
- Школьные учебники
- Детский фольклор
- Книги для дошкольников
- Детские детективы
- Детская познавательная и развивающая литература
- Буквари
- Прочая детская литература
- Сказка
- Детская проза
- Детская образовательная литература
- Юмор
- Документальные книги
- Бизнес
- Внешнеэкономическая деятельность
- Тайм-менеджмент
- Кадровый менеджмент
- О бизнесе популярно
- Управление, подбор персонала
- Бизнес
- Менеджмент и кадры
- Продажи
- Экономика
- Ценные бумаги и инвестиции
- Малый бизнес
- Делопроизводство, офис
- Корпоративная культура, бизнес
- Банковское дело
- Финансы
- Зарубежная деловая литература
- Ораторское искусство / риторика
- Личные финансы
- Интернет-бизнес
- Поиск работы
- Государственное и муниципальное управление
- Бухучет и аудит
- Работа с клиентами
- Менеджмент
- Краткое содержание
- Личная эффективность
- Переговоры
- Приключения
- Старинная литература
- Религия и духовность
- Компьютеры и Интернет
- Блог
Читаем без скачивания C++17 STL Стандартная библиотека шаблонов - Яцек Галовиц
Шрифт:
Интервал:
Закладка:
1. На сей раз нам понадобится только iostream. Так что включим этот единственный заголовочный файл и объявим об использовании пространства имен std по умолчанию:
#include <iostream>
using namespace std;
2. Пригласим пользователя ввести два числа. Поместим их в переменные типов int и double. Пользователь может разделить их пробелами. Например, 1 2.3 — это корректные входные данные.
int main()
{
cout << "Please Enter two numbers:n> ";
int x;
double y;
3. Анализ и проверка ошибок выполняются одновременно в условной части блока if. Выведем числа на экран только в том случае, если их можно проанализировать и они имеют смысл:
if (cin >> x >> y) {
cout << "You entered: " << x
<< " and " << y << 'n';
4. Если по какой-то причине анализ завершился ошибкой, то мы скажем пользователю об этом. Объект потока cin теперь находится в состоянии ошибки и не будет давать другие данные до тех пор, пока мы не избавимся от этого состояния. Чтобы иметь возможность проанализировать новые входные данные после ошибки, вызываем метод cin.clear() и отбрасываем все входные данные, полученные ранее. Отбрасывание выполняется с помощью cin.ignore, где мы указываем, что нужно отбросить максимальное количество символов до тех пор, пока не встретим символ новой строки (который тоже будет отброшен). После этого символа снова начинаются интересные входные данные:
} else {
cout << "Oh no, that did not go well!n";
cin.clear();
cin.ignore(
std::numeric_limits<std::streamsize>::max(),
'n');
}
5. Теперь запросим еще какие-нибудь входные данные. Мы позволим пользователю вводить имена. Они могут состоять из нескольких слов, разделенных пробелами, поэтому символ пробела не подходит в качестве разделителя. Так что воспользуемся std::getline, принимающим объектом потока наподобие cin, ссылкой на строку, в которую будут скопированы входные данные, и символом-разделителем (таковым выступит запятая ','). Задействуя вместо cin конструкцию cin >> ws в качестве параметра потока для getline, можно дать cin команду отбросить пробелы, стоящие перед именами. На каждом шаге цикла выводим текущее имя, но если оно пустое, то завершим цикл:
cout << "now please enter some "
"comma-separated names:n> ";
for (string s; getline(cin >> ws, s, ',');) {
if (s.empty()) { break; }
cout << "name: "" << s << ""n";
}
}
6. Компиляция и запуск программы дадут следующий результат (для него предполагается введение только корректных значений). Мы ввели числа "1 2", они были преобразованы корректно, а затем ввели некоторые имена, также корректно выведенные на экран. Пустое имя, полученное в виде двух запятых, расположенных рядом друг с другом, завершает цикл:
$ ./strings_from_user_input Please Enter two numbers:
> 1 2
You entered: 1 and 2
now please enter some comma-separated names:
> john doe, ellen ripley, alice, chuck norris,,
name: "john doe"
name: "ellen ripley"
name: "alice"
name: "chuck norris"
7. При повторном запуске программы и вводе некорректных цифр в самом начале мы увидим, что программа корректно выбирает другую ветвь, отбрасывает некорректные данные и продолжает работу с помощью слушателя имен. Попробуйте использовать строки cin.clear() и cin.ignore(...), чтобы увидеть, как это пересекается с кодом чтения имен:
$ ./strings_from_user_input
Please Enter two numbers:
> a b
Oh no, that did not go well!
now please enter some comma-separated names:
> bud spencer, terence hill,,
name: "bud spencer"
name: "terence hill"
Как это работает
В этом разделе мы выполнили сложную операцию получения входных данных. Первое, на что следует обратить внимание: получение данных и проверка на ошибки всегда происходили одновременно.
Результатом выполнения выражения cin >> x является ссылка на cin. Таким образом можно создавать конструкции наподобие cin >> x >> y >> z >> .... В то же время можно преобразовать данные к булевым значениям, используя их в булевых контекстах, таких как условие if. Булево значение говорит нам, была ли корректной последняя операция чтения. Вот почему можно создавать конструкции, аналогичные выражению if (cin >> x >> y){...}.
Если мы, например, попробуем считать целое число, но во входных данных следующим является токен "foobar", то преобразование этого значения к типу int выполнить нельзя и объект потока входит в ошибочное состояние. Это критически важно только для попытки преобразования, но не для всей программы. Можно совершенно спокойно сбросить ее и попробовать сделать что-то еще. В нашем примере мы попробовали считать список имен после потенциально ошибочной попытки считать два числа. При неудачной попытке считывания числа мы используем функцию cin.clear() с целью вернуть cin в рабочее состояние. Но после этого его внутренний курсор все еще находится в той позиции, где лежат данные, которые мы ввели вместо чисел. Чтобы отбросить старые входные данные и очистить канал для ввода имен, мы применили очень длинное выражение, cin.ignore(std::numeric_limits<std::streamsize>::max(), 'n');. Необходимо удалять все, что находилось в буфере, поскольку он нужен абсолютно пустым, когда мы запросим у пользователя список имен.
Следующий цикл также может показаться странным на первый взгляд:
for (string s; getline(cin >> ws, s, ',');) { ... }
В условной части цикла мы использовали функцию getline. Она принимает объект потока ввода, ссылку на строку в качестве выходного параметра, а также символ-разделитель. По умолчанию таковым является символ перехода на новую строку. Здесь мы указали, что в роли этого символа выступает запятая (,), чтобы все имена из списка наподобие "john, carl, frank" считывались отдельно.
Пока все идет по плану. Но что означает предоставление функции cin >> ws в качестве объекта потока? Это заставляет cin отбросить все пробелы, которые стоят перед следующим символом, не являющимся пробелом, а также в конце строки. Если бы мы не применили ws, то из строки "john, carl, frank" получили бы подстроки "john", " carl" и " frank". Заметили лишние пробелы для имен