Чтение номеров ввода, разделенных пробелами
Это может быть полный вопрос новичка, но я еще не нашел ответ, который работает для меня.
В настоящее время я пишу программу для класса, которая принимает пользовательский ввод (который может быть одним или несколькими числами, разделенными пробелами), а затем определяет, является ли число простым, совершенным или ни того, ни другого. Если число идеально, то он будет отображать делители.
До сих пор я уже написал код для простого, совершенного и перечисления делителей. Я застрял на входной части моей программы. Я не знаю, как получить входные данные, разделенные пробелами, чтобы пройти через мои циклы по одному.
Это моя текущая программа:
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;
Это работает, но только для одного номера. Если бы кто-нибудь мог помочь мне сделать так, чтобы он мог читать несколько входов, разделенных пробелами, это было бы очень признательно. Кроме того, просто примечание, я не знаю, сколько чисел будет введено, поэтому я не могу просто сделать переменную для каждого. Это будет случайное количество чисел.
Спасибо!
Ответы
Ответ 1
По умолчанию 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
Ответ 2
Я бы рекомендовал читать строку в строке, а затем разбивать ее на основе пробелов. Для этого вы можете использовать функцию 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-строку вместо строки стиля С++, мы используем 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 (...). Здесь важно обратить внимание на то, что строки стиля С++ можно использовать как массив, так как rawInput [0] - это первый символ в строке вплоть до rawInput [длина - 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 используется для определения того, нужно ли делать ваши вещи или печатать сообщение об ошибке.
Ответ 3
Вы хотите:
- Прочитайте всю строку с консоли
- Токенизировать линию, расщепляясь вдоль пробелов.
- Поместите эти фрагменты в массив или список
- Пройдите через этот массив/список, выполнив ваши тесты Prime/Perfect/etc.
Каким будет ваш класс по этим линиям?