Чтение входных чисел, разделенных пробелами

Это может быть вопрос для новичков, но мне еще предстоит найти ответ, который работает для меня.

В настоящее время я пишу программу для класса, который принимает пользовательский ввод (который может быть одним или несколькими числами, разделенными пробелами), а затем определяет, является ли число простым, совершенным или ни тем, ни другим. Если число идеальное, то оно будет отображать делители.

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

Это моя текущая программа:

cout<<"Enter a number, or numbers separated by a space, between 1 and 1000."<<endl;
cin>>num;

while (divisor<=num)
    if(num%divisor==0)
    {
        cout<<divisor<<endl;
        total=total+divisor;
        divisor++;
    }
    else divisor++;
if(total==num*2)
    cout<<"The number you entered is perfect!"<<endl;
else cout<<"The number you entered is not perfect!"<<endl;


if(num==2||num==3||num==5||num==7)
    cout<<"The number you entered is prime!"<<endl;

else if(num%2==0||num%3==0||num%5==0||num%7==0)
    cout<<"The number you entered is not prime!"<<endl;
else cout<<"The number you entered is prime!"<<endl;

return 0;

Это работает, но только для одного номера. Если бы кто-нибудь мог помочь мне заставить его читать несколько входов, разделенных пробелами, я был бы очень признателен. Кроме того, просто примечание: я не знаю, сколько чисел будет введено, поэтому я не могу просто создать переменную для каждого из них. Это будет случайное количество чисел.

Спасибо!


person Raymond Aaron    schedule 27.10.2012    source источник
comment
См. SO: чтение строки целых чисел в вектор   -  person MTV    schedule 25.08.2020


Ответы (4)


По умолчанию cin читает из ввода, отбрасывая любые пробелы. Итак, все, что вам нужно сделать, это использовать цикл do while для чтения ввода более одного раза:

do {
   cout<<"Enter a number, or numbers separated by a space, between 1 and 1000."<<endl;
   cin >> num;

   // reset your variables

   // your function stuff (calculations)
}
while (true); // or some condition
person Murilo Vasconcelos    schedule 27.10.2012
comment
Каждый cin будет пытаться прочитать число из ввода. Итак, да, он будет читать следующий номер, как вы можете видеть в этом примере: ideone.com/ZHvdVx. - person Murilo Vasconcelos; 27.10.2012
comment
Теперь, когда программа работает правильно и показывает все числа, проблема с форматированием. Пример: Вы ввели число 6. 1 2 3 6 6 идеально! Я хочу, чтобы 6 была идеальной на следующей строке. Итак, когда он доходит до последнего числа перед запуском нового цикла с другим номером, есть ли способ заставить его перейти на другую строку? - person Raymond Aaron; 27.10.2012
comment
Да, есть. Всякий раз, когда вам нужна новая строка, вы можете cout и '\n'. - person Murilo Vasconcelos; 27.10.2012
comment
Спасибо за вашу помощь, ребята! Мне просто нужно выяснить, как сделать так, чтобы отображалось не более 7 чисел в строке. Вы, ребята, лучшие! ^_^ - person Raymond Aaron; 27.10.2012
comment
Пытался выяснить, как сделать цикл программы снова, если пользователь желает. Я спрашиваю, не хотят ли они снова запустить программу, но я не могу заставить ее запустить цикл с самого начала. Любые идеи? - person Raymond Aaron; 30.10.2012

Я бы рекомендовал читать строку в строку, а затем разбивать ее на основе пробелов. Для этого вы можете использовать функцию getline(...). Хитрость заключается в наличии структуры данных динамического размера для хранения строк после их разделения. Вероятно, проще всего использовать vector.

#include <string>
#include <vector>
...
  string rawInput;
  vector<String> numbers;
  while( getline( cin, rawInput, ' ' ) )
  {
    numbers.push_back(rawInput);
  }

Итак, скажем, ввод выглядит так:

Enter a number, or numbers separated by a space, between 1 and 1000.
10 5 20 1 200 7

Теперь у вас будет вектор чисел, который содержит элементы: {"10","5","20","1","200","7"}.

Обратите внимание, что это все еще строки, поэтому они бесполезны в арифметике. Чтобы преобразовать их в целые числа, мы используем комбинацию функции STL, atoi(...), и поскольку atoi требует c-строки вместо строки в стиле C++, мы используем string class' c_str() функция-член.

while(!numbers.empty())
{
  string temp = numbers.pop_back();//removes the last element from the string
  num = atoi( temp.c_str() ); //re-used your 'num' variable from your code

  ...//do stuff
}

Теперь есть некоторые проблемы с этим кодом. Да, он работает, но немного неуклюже и выводит числа в обратном порядке. Давайте перепишем его так, чтобы он был немного более компактным:

#include <string>
...
string rawInput;
cout << "Enter a number, or numbers separated by a space, between 1 and 1000." << endl;
while( getline( cin, rawInput, ' ') )
{
  num = atoi( rawInput.c_str() );
  ...//do your stuff
}

Есть еще много возможностей для улучшения обработки ошибок (прямо сейчас, если вы введете не число, программа рухнет), и есть бесконечно больше способов действительно обработать ввод, чтобы получить его в пригодной для использования числовой форме (радости программирования! ), но это должно дать вам всестороннее начало. :)

Примечание. У меня были справочные страницы в виде ссылок, но я не могу опубликовать более двух, так как у меня менее 15 сообщений :/

Редактировать: я немного ошибся в поведении atoi; Я перепутал это с преобразованием Java в string->Integer, которое выдает исключение Not-A-Number, когда задана строка, не являющаяся числом, а затем приводит к сбою программы, если исключение не обрабатывается. atoi(), с другой стороны, возвращает 0, что не так полезно, потому что что, если 0 — это число, которое они ввели? Воспользуемся функцией isdigit(...). Здесь важно отметить, что доступ к строкам стиля C++ можно получить как к массиву, то есть rawInput[0] является первым символом в строке вплоть до rawInput[length - 1].

#include <string>
#include <ctype.h>
...
string rawInput;
cout << "Enter a number, or numbers separated by a space, between 1 and 1000." << endl;
while( getline( cin, rawInput, ' ') )
{
  bool isNum = true;
  for(int i = 0; i < rawInput.length() && isNum; ++i)
  {
    isNum = isdigit( rawInput[i]);
  }

  if(isNum)
  {
    num = atoi( rawInput.c_str() );
    ...//do your stuff
  }
  else
    cout << rawInput << " is not a number!" << endl;
}

Логическое значение (true/false или 1/0 соответственно) используется в качестве флага для цикла for, который проходит через каждый символ в строке и проверяет, является ли он цифрой 0-9. Если какой-либо символ в строке не является цифрой, цикл прервется во время его следующего выполнения, когда он дойдет до условия «&& isNum» (при условии, что вы уже прошли циклы). Затем, после цикла, isNum используется для определения того, следует ли выполнять ваши действия или распечатать сообщение об ошибке.

person Logan Nichols    schedule 27.10.2012
comment
Ух ты. Ха, ты должен быть моим профессором. Спасибо за вашу помощь! Всегда здорово узнавать новые способы делать вещи! Кстати, я собираюсь добавить код, который говорит, что если они введут что-то, что не является целым числом, он спросит их, хотят ли они попробовать программу еще раз. Класс простой, поэтому мне не нужно заниматься самым экстравагантным программированием, но я хотел бы знать, как это сделать, и иметь это в своем банке (в уме), когда я хочу немного покрасоваться. ;] Большое спасибо за вашу помощь! - person Raymond Aaron; 27.10.2012
comment
@RaymondAaron: Нет проблем! Я отредактирую сообщение, чтобы включить ваш другой вопрос, поскольку форматирование в комментариях довольно ограничено. - person Logan Nichols; 28.10.2012

Вы захотите:

  • Чтение всей строки из консоли
  • Обозначьте линию, разбивая ее по пробелам.
  • Поместите эти разделенные части в массив или список
  • Пройдитесь по этому массиву/списку, выполняя тесты Prime/Perfect/etc.

Что ваш класс изучил в этом направлении до сих пор?

person ravuya    schedule 27.10.2012
comment
Как ни странно, ничего. Я не понимаю, как мы должны это делать. Я просматривал массивы в нашем тексте и не совсем понял, как это работает в моей программе. Наверное, я просто не знаю, как это сделать правильно. - person Raymond Aaron; 27.10.2012

int main() {
int sum = 0;
cout << "enter number" << endl;
int i = 0;
while (true) {
    cin >> i;
    sum += i;
    //cout << i << endl;
    if (cin.peek() == '\n') {
        break;
    }
    
}

cout << "result: " << sum << endl;
return 0;
}

Я думаю, что этот код работает, вы можете ввести любые целые числа и пробелы, он рассчитает сумму введенных целых чисел

person waw waw    schedule 07.09.2020