Как прочитать неизвестное количество входов? - PullRequest
0 голосов
/ 30 мая 2018

Я изучаю C ++, используя книгу C ++ Primer.

В Раздел 1.4.3 , приведен следующий пример кода для чтения неизвестного количества входных данных.

#include <iostream>
int main()
{
  int sum = 0, value = 0;
  // read until end-of-file, calculating a running total of all values read
  while (std::cin >> value)
  sum += value; // equivalent to sum = sum + value
  std::cout << "Sum is: " << sum << std::endl;
  return 0;
}

Согласно книге, если мы введем 3 4 5 6, вывод будет Sum is: 18

Но когда я попробую это сделать на моем компьютере ( Windows 10 с MinGW * 1013)*), Код не заканчивается.Он просто продолжает запрашивать ввод, даже если я вхожу на новую строку.Это работает только тогда, когда я ввожу не-int ввод, такой как f.


Ожидается ли это?Если да, есть ли какой-нибудь код, который останавливается после ввода новой строки?

Я довольно новичок в c ++, и я уже выучил python, поэтому застревание на столь раннем этапе довольно разочаровывает.


Спасибо и всего наилучшего.

Ответы [ 3 ]

0 голосов
/ 30 мая 2018

Ожидается ли это?

Да , Вот что делает while (std::cin >> value).См. Этот ответ для более подробных объяснений: Как вычисляется "std :: cin >> value" в цикле while?

Есть ли код, который останавливается после ввода новой строки?

Нет , поскольку >> просто игнорирует пробел (также @StephanLechner упомянул это)

Вместо этого вы можете сделать:

  1. Просто дайте условие;если он удовлетворяет только break цикл.Вы также можете предоставить консоль, чтобы сделать ее более понятной для пользователя.Например:

    std::cout << "Enter value to sum or press -1 to exit" << std::endl;
    
    while (std::cin >> value && value != -1) // if value == -1, loop stops.
    {
        sum += value;
    }
    
  2. Вы можете просто завершить к концу символа:

    • CTRL-Z в Windows
    • CTRL-D на Mac / Unix
0 голосов
/ 30 мая 2018

Ожидается ли это?

Да, поскольку operator>> по умолчанию игнорирует начальные пробелы, включая разрывы строк.

Если да, есть лилюбой код, который останавливается после ввода новой строки?

Используйте std::cin.getline() или std::getline() вместо operator>>.Затем вы можете использовать operator>> с std::istringstream для анализа значений из каждой строки, например:

#include <iostream>
#include <string>
#include <sstream>

int main()
{
    std::string line;
    int sum, value;

    do
    {
        std::cout << "Enter a set of numbers, or a blank line to exit: ";
        if (!std::getline(std::cin, line) || line.empty())
            break;

        // read until end-of-line, calculating a running total of all values read
        std::istringstream iss(line);
        sum = 0;
        while (iss >> value)
            sum += value; // equivalent to sum = sum + value

        std::cout << "Sum is: " << sum << std::endl;
    }
    while (true);

    return 0;
}

Live Demo

0 голосов
/ 30 мая 2018

Вам необходимо завершить ввод с помощью символа конца файла (например, CTRL-Z в Windows, CTRL-D в Mac / Unix), а не толькоконец строки (т. е. Enter ).

Простое Enter интерпретируется как пробел, который будет просто игнорироваться operator>> при чтении ввстроенный тип данных.

CTRL-Z / Конец файла, напротив, приводит к сбою любого operator>> с ошибкой.

См. также этот SO-ответ .

Примечание. Ввод f также завершит ваш цикл, поскольку f не считается действительным целым числом;Следовательно, std::cin >> value с value типа int и входом типа f также потерпит неудачу.Чтобы быть более точным: operator>> фактически возвращает ссылку на входной поток, но если не удается прочитать значение, в потоке устанавливается failbit, а затем интерпретируется объект потока в логическом выражении (неявно вызывая basic_istream::operator bool()) возвращает false;Поэтому, возможно, автор книги не хотел объяснять эти детали в соответствующем разделе книги: -)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...