C++ 读取以空格分隔的输入数字

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13096719/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 16:57:22  来源:igfitidea点击:

Read input numbers separated by spaces

c++inputspaces

提问by Raymond Aaron

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!

谢谢!

采纳答案by Murilo Vasconcelos

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

默认情况下,cin从输入中读取并丢弃任何空格。因此,您所要做的就是使用 dowhile循环多次读取输入:

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

回答by Logan Nichols

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.

我建议将行读入一个字符串,然后根据空格将其拆分。为此,您可以使用getline(...)函数。诀窍是拥有一个动态大小的数据结构来保存字符串一旦被拆分。可能最容易使用的是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"}.

您现在将拥有一个向量,数字,其中包含以下元素:{"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 stringclass' c_str()member function.

请注意,这些仍然是字符串,因此在算术中没有用。要将它们转换为整数,我们使用 STL 函数 atoi(...) 的组合,并且因为 atoi 需要一个 c 字符串而不是 c++ 样式的字符串,所以我们使用字符串类的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
}

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 :/

注意:我有参考页面作为链接,但我不能发布超过两个,因为我的帖子少于 15 个:/

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].

编辑:我对 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;
}

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.

布尔值(分别为 true/false 或 1/0)用作 for 循环的标志,循环遍历字符串中的每个字符并检查它是否为 0-9 数字。如果字符串中的任何字符不是数字,则循环将在下一次执行期间达到条件“&& isNum”时中断(假设您已经涵盖了循环)。然后在循环之后, isNum 用于确定是否执行您的操作,或打印错误消息。

回答by ravuya

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?

到目前为止,您的课程在这些方面涵盖了哪些内容?