Read input numbers separated by spaces
Asked Answered
R

6

34

This may be a total beginner's question, but I have yet to find an answer that works for me.

Currently, I'm writing a program for a class that takes in a user's input (which can be one or more numbers separated by spaces), then determines whether the number is prime, perfect, or neither. If the number is perfect, then it will display the divisors.

Thus far, I've already written the code for the prime, perfect, and listing the divisors. I'm stuck on the input portion of my program. I don't know how to get the input that's separated by spaces to go through my loops one at a time.

This is my current program:

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;

It works, but only for a single number. If anyone could help me to get it to be able to read multiple inputs separated by spaces, it'd be greatly appreciated. Also, just a side note, I do not know how many numbers will be entered, so I can't just make a variable for each one. It will be a random amount of numbers.

Thanks!

Rolo answered 27/10, 2012 at 2:30 Comment(1)
See SO: Reading a Line of Integers Into VectorAnticipation
E
25

By default, cin reads from the input discarding any spaces. So, all you have to do is to use a do while loop to read the input more than one time:

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
Empennage answered 27/10, 2012 at 2:34 Comment(5)
Each cin will try to read a number from the input. So, yes, it will read the next number as you can see in this example: ideone.com/ZHvdVxEmpennage
Now that I have the programming working correctly and showing all the numbers, the formatting is an issue. Ex:" The number you entered is 6. 1 2 3 6 6 is perfect!" I want the "6 is perfect on the next line. So, when it gets to the last number before starting the new loop with a different number, is there a way to get it to change to a different line?Rolo
Yes, there is. Whenever you want a new line, you can cout a '\n'.Empennage
Thanks for all your help, guys! I just have to figure out how to make it so only displays 7 numbers max per line. You guys are the best! ^_^Rolo
Been trying to figure out how to make the program loop through again, if the user desires. I ask if they would like to run the program again, but I can't get it to loop through the beginning. Any ideas?Rolo
S
23

I would recommend reading in the line into a string, then splitting it based on the spaces. For this, you can use the getline(...) function. The trick is having a dynamic sized data structure to hold the strings once it's split. Probably the easiest to use would be a vector.

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

So say the input looks like this:

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

You will now have a vector, numbers, that contains the elements: {"10","5","20","1","200","7"}.

Note that these are still strings, so not useful in arithmetic. To convert them to integers, we use a combination of the STL function, atoi(...), and because atoi requires a c-string instead of a c++ style string, we use the string class' c_str() member function.

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
}

Now there's some problems with this code. Yes, it runs, but it is kind of clunky, and it puts the numbers out in reverse order. Lets re-write it so that it is a little more compact:

#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
}

There's still lots of room for improvement with error handling (right now if you enter a non-number the program will crash), and there's infinitely more ways to actually handle the input to get it in a usable number form (the joys of programming!), but that should give you a comprehensive start. :)

Note: I had the reference pages as links, but I cannot post more than two since I have less than 15 posts :/

Edit: I was a little bit wrong about the atoi behavior; I confused it with Java's string->Integer conversions which throw a Not-A-Number exception when given a string that isn't a number, and then crashes the program if the exception isn't handled. atoi(), on the other hand, returns 0, which is not as helpful because what if 0 is the number they entered? Let's make use of the isdigit(...) function. An important thing to note here is that c++ style strings can be accessed like an array, meaning rawInput[0] is the first character in the string all the way up to 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;
}

The boolean (true/false or 1/0 respectively) is used as a flag for the for-loop, which steps through each character in the string and checks to see if it is a 0-9 digit. If any character in the string is not a digit, the loop will break during it's next execution when it gets to the condition "&& isNum" (assuming you've covered loops already). Then after the loop, isNum is used to determine whether to do your stuff, or to print the error message.

Smokeless answered 27/10, 2012 at 3:54 Comment(2)
Wow. Ha, you should be my professor. Thanks for all your help! It's always great learning new ways to do things! On a side note, I'm about to put in the code that says that if they enter anything that isn't an intiger, that it will ask them if they want to try the program again. The class is simple, so I don't need to do the most extravagant programming, but I'd like to know how to do it and have it in my bank (mind), for when I want to show off a bit. ;] Thanks a lot for all your help!Rolo
@RaymondAaron: No problem! I'll edit the post to include your other question since formatting is rather limited in comments.Smokeless
C
6

You'll want to:

  • Read in an entire line from the console
  • Tokenize the line, splitting along spaces.
  • Place those split pieces into an array or list
  • Step through that array/list, performing your prime/perfect/etc tests.

What has your class covered along these lines so far?

Caligula answered 27/10, 2012 at 2:34 Comment(1)
Oddly enough, nothing. I don't see how we're expected to do it. I was looking at arrays in our text, and I haven't quite figured it out to work in my program. I guess I just don't know how to do it correctly.Rolo
E
5
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;
}

I think this code works, you may enter any int numbers and spaces, it will calculate the sum of input ints

Ellieellinger answered 7/9, 2020 at 20:2 Comment(0)
C
0
std::vector<int> num{};
int buf;

    do{
        std::cin >> buf;
        num.push_back(buf);
    }while(std::cin.peek() == ' ');
Cadal answered 8/4, 2022 at 12:17 Comment(0)
W
-2

In C language you can to it using scanf like this:

scanf('%d %d',&a,&b);
Wert answered 6/5, 2022 at 18:9 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.