Kniga-Online.club
» » » » C++17 STL Стандартная библиотека шаблонов - Яцек Галовиц

C++17 STL Стандартная библиотека шаблонов - Яцек Галовиц

Читать бесплатно C++17 STL Стандартная библиотека шаблонов - Яцек Галовиц. Жанр: Программирование год 2004. Так же читаем полные версии (весь текст) онлайн без регистрации и SMS на сайте kniga-online.club или прочесть краткое содержание, предисловие (аннотацию), описание и ознакомиться с отзывами (комментариями) о произведении.
Перейти на страницу:
входных данных, чтобы разбить их на полезные фрагменты.

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". Заметили лишние пробелы для имен

Перейти на страницу:

Яцек Галовиц читать все книги автора по порядку

Яцек Галовиц - все книги автора в одном месте читать по порядку полные версии на сайте онлайн библиотеки kniga-online.club.


C++17 STL Стандартная библиотека шаблонов отзывы

Отзывы читателей о книге C++17 STL Стандартная библиотека шаблонов, автор: Яцек Галовиц. Читайте комментарии и мнения людей о произведении.


Уважаемые читатели и просто посетители нашей библиотеки! Просим Вас придерживаться определенных правил при комментировании литературных произведений.

  • 1. Просьба отказаться от дискриминационных высказываний. Мы защищаем право наших читателей свободно выражать свою точку зрения. Вместе с тем мы не терпим агрессии. На сайте запрещено оставлять комментарий, который содержит унизительные высказывания или призывы к насилию по отношению к отдельным лицам или группам людей на основании их расы, этнического происхождения, вероисповедания, недееспособности, пола, возраста, статуса ветерана, касты или сексуальной ориентации.
  • 2. Просьба отказаться от оскорблений, угроз и запугиваний.
  • 3. Просьба отказаться от нецензурной лексики.
  • 4. Просьба вести себя максимально корректно как по отношению к авторам, так и по отношению к другим читателям и их комментариям.

Надеемся на Ваше понимание и благоразумие. С уважением, администратор kniga-online.


Прокомментировать
Подтвердите что вы не робот:*
Подтвердите что вы не робот:*