如何检查cin中的空间分隔输入是否为严格双输入

How to check space separated inputs in cin to be strictly doubles?

本文关键字:输入 是否 分隔 空间 何检查 检查 cin      更新时间:2023-10-16

我有一个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; 

输入:12 3输出:12 3

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

在第二种情况下,我想检测是否存在错误,以及哪些术语不是有效的Double,并列出它们:

错误消息:第一个、第二个和第三个不是有效的替身。

如果我检查无效值(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;
  }

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

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

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

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

我建议您使用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;
  }
}
    #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

我认为你可以在这方面走很长的路。