如何检查cin中的空格分隔输入是否严格加倍?

时间:2016-08-14 14:08:41

标签: c++ cin

我有一个C ++程序,需要一组由空格分隔的正双精度作为输入,然后打印出来。

我输入了三个由逗号+空格分隔的值(错误地),第一个数字被正确打印,其他数字没有。如何检查每个值是否正确并列出所有错误的值?

cout << "Enter three positive numbers separated by spaces" << endl;
double a = 0, b = 0, c = 0;
cin >> a >> b >> c;
cout << a << ' ' << b << ' ' << c << endl; 
  

输入:1 2 3输出:1 2 3

     

输入:1,2,3输出:1 0 0

在第二种情况下,我想检测出有错误,哪些条款无效,并列出它们:

  

错误消息:第一个,第二个和第三个不是有效的双打。

如果我检查无效值(0),我会捕获2和3,但不会是1,因为它似乎接受1.

更新:基于以下答案的代码(它仍然首先将上述输入视为正确,第二个视为错误,但首先也应该是错误的):

  cout << "Enter three numbers separated by spaces" << endl;
  double a = 0, b = 0, c = 0;
  if(cin >> a) 
  {
    cout << "first number was correct" << endl;
    if(cin >> b) 
    {
      cout << "second number was correct" << endl;
      if(cin >> c)
      {
        cout << "third number was correct" << endl;
        cout << a << " " << b << " " << c << endl;
      }
      else
      {
        cout << "third number was wrong" << endl;
      }
    }
    else
    {
      cout << "second number was wrong" << endl;
    }
  }
  else
  {
    cout << "first number was wrong" << endl;
  }

3 个答案:

答案 0 :(得分:1)

您可以测试cin的状态,以查看是否有任何操作失败。如果cin.good()为真,那么到目前为止一切都很好。

测试整个输入的最简单方法是将其放在if语句中

if (cin >> a >> b >> c)
   cout << "fine";
else
  cout << "something went wrong";

如果您想要更细粒度的结果,您可能希望一次读取一个变量,并检查每次读取之间的状态。

答案 1 :(得分:1)

我建议你使用boost。

std::string input;
std::getline(std::cin, input);
std::vector<std::string> numbers;
split(numbers, input, is_any_of(" \t"), token_compress_on);
for (const std::string& number : numbers)
{
  try
  {
    double value = boost::lexical_cast<double>(number);
    std::cout << number << " is a number" << std::endl;
  }
  catch (const boost::lexical_cast&)
  {
    std::cout << number << " is not a number" << std::endl;
  }
}

答案 2 :(得分:-2)

    #include <iostream>
#include <sstream>
#include <vector>

using namespace std;

template<typename T>
bool validatedCoercion(string input, T &dest) {
    istringstream iss(input);
    if(!(iss >> dest)) return false;
    return iss.rdbuf()->in_avail() == 0;
}

vector<string> splitByCommaOrSpace(const string& input) {
    vector<string> result;
    string buffer;
    bool ok = true;
    for(char c : input) {
        if((c == ',' || isspace(c)) && buffer.size() != 0) {
            result.push_back(buffer);
            buffer = "";
        } else {
            buffer += c;
        }
    }
    if(buffer.size() != 0) {
        result.push_back(buffer);
    }
    return result;
}


int main()
{
    const int N = 3;
    double x[N] = {-1};

    string line;
    getline(cin, line);
    if(!cin) {
        cerr << "An error occured while reading from stdin." << endl;
    }

    auto doubles = splitByCommaOrSpace(line);
    if(doubles.size() != N) {
        cerr << "Invalid number of input, expected " << N << " got " << doubles.size() << endl;
    }

    int i = 1;
    for(string& s : doubles) {
        if(!validatedCoercion(s, x[i-1])) {
            cout << "column " << i << " is not a valid number.\n";
        }
        i++;
    }

    i = 1;
    for(double d : x) {
        if(x > 0) {
            cout << "number " << i << " is positive.\n";
        } else {
            cout << "number " << i << " is invalid (not strictly positive).\n";
        }
        i++;
    }

    i = 1;
    for(double d : x) {
        cout << "number " << i++ << " is " << x[i-1] << "\n";
    }
    return 0;
}

示例1:

12.32, 43,2
number was 1 correct.
number was 2 correct.
number was 3 correct.
number 1 is 12.32
number 2 is 43
number 3 is 2

示例2:

1.3 23 4
number was 1 correct.
number was 2 correct.
number was 3 correct.
number 1 is 1.3
number 2 is 23
number 3 is 4

示例3:

1 2d 3sd
number was 1 correct.
number was 2 wrong.
number was 3 wrong.
number 1 is 1
number 2 is 2
number 3 is 3

示例5:

a b
Invalid number of input, expected 3 got 2
number was 1 wrong.
number was 2 wrong.
number 1 is 0
number 2 is 0
number 3 is 0

示例6(更新的代码):

1 -2 a
column 3 is not a valid number.
number 1 is positive.
number 2 is positive.
number 3 is positive.
number 1 is 1
number 2 is -2
number 3 is 0

我认为你可以在很长的路要走。