C++ C++;指定来自istream的输入并对其进行测试

C++ C++;指定来自istream的输入并对其进行测试,c++,c++11,testing,istream,C++,C++11,Testing,Istream,我有一个基本上表示元组的类(双x,双y),我重载了>,因此它只支持以下格式: x、 (x)和(x,y) 我有以下代码: std::ostream & operator<< (std::ostream &output, tuple &c){ output << "(" << c.x << "," << c.y << ")" << endl; return output; }

我有一个基本上表示元组的类(双x,双y),我重载了>,因此它只支持以下格式: x、 (x)和(x,y)

我有以下代码:

std::ostream & operator<< (std::ostream &output, tuple &c){
    output << "(" << c.x << "," << c.y << ")" << endl;
    return output;
}

std::istream & operator>> (std::istream & input, tuple &c){
    // Check for following patterns: x, (x) or (x,y)
}

对于这样一个简单的输入任务,
std::ostream&operatorRegex是不必要的。下面是我将如何做到这一点,无需检查是否存在有效输入,只需解析即可:

std::istream & operator>> (std::istream & input, tuple &c){
    // Check for following patterns: x, (x) or (x,y)
    char firstCharacter;
    input >> firstCharacter; // See what the first character is, since it varies

    if (firstCharacter == '(')
    {   // The simplest case, since the next few inputs are of the form n,n)
        char delimiters;
        input >> c.x >> delimiters >> c.y >> delimiters;
        //        N        ,           N        )
        // You also here have to check whether the above inputs are valid, 
        // such as if the user enters a string instead of a number
        // or if the delimeters are not commas or parentheses
    }
    else if (isdigit(firstCharacter) || firstCharacter == '-')
    {   //                               For negative numbers
        char delimiters;
        input.unget(); // Put the number back in the stream and read a number
        input >> c.x >> delimiters >> delimiters >> c.y >> delimiters;
        //        N           ,         (            N          )
        // You also here have to check whether the above inputs are valid, 
        // such as if the user enters a string instead of a number
        // or if the delimeters are not commas or parentheses
    }
    else
    { 
        // Handle some sort of a parsing error where the first character 
        // is neither a parenthesis or a number
    }

    return input;
}

派对有点晚了,但这里有一个正则表达式解决方案。虽然它并不漂亮,但它允许输入负数和科学记数法。它还允许数字之间存在空格:

#include <iostream>
#include <regex>
#include <tuple>

std::istream &operator>> (std::istream &input, std::tuple<double, double> &t)
{
    std::smatch m;
    std::string s;
    if (std::getline(input, s))
    {
        if (std::regex_match(s, m, std::regex(R"(\s*([-+]?\d*\.?\d+(?:[eE][-+]?\d+)?)\s*)"))) //x
            t = std::move(std::make_tuple(std::stod(m[1]), 0.0));
        else if (std::regex_match(s, m, std::regex(R"(\s*\(\s*([-+]?\d*\.?\d+(?:[eE][-+]?\d+)?)\s*\)\s*)"))) //(x)
            t = std::move(std::make_tuple(std::stod(m[1]), 0.0));
        else if (std::regex_match(s, m, std::regex(R"(\s*\(\s*([-+]?\d*\.?\d+(?:[eE][-+]?\d+)?)\s*,\s*([-+]?\d*\.?\d+(?:[eE][-+]?\d+)?)\s*\)\s*)"))) //(x,y)
            t = std::move(std::make_tuple(std::stod(m[1]), std::stod(m[2])));
    }
    return input;
}


int main() 
{
    std::tuple <double, double> t;
    std::cout << "Enter data in format num, (num) or (num1,num2): ";
    std::cin >> t;
    std::cout << "Tuple 0: " << std::get<0>(t) << std::endl;
    std::cout << "Tuple 1: " << std::get<1>(t) << std::endl;

    return 0;

} 
#包括
#包括
#包括
std::istream和运算符>>(std::istream和输入,std::元组和t)
{
std::smatch m;
std::字符串s;
if(std::getline(输入,s))
{
如果(std::regex_匹配(s,m,std::regex(R)(\s*([-+]?\d*\。?\d+(?:[eE][-+]?\d+))))/x
t=std::move(std::make_tuple(std::stod(m[1]),0.0));
如果(std::regex\u匹配(s,m,std::regex(R)(\s*\(\s*([-+]?\d*\?\d+(?:[eE][-+]?\d+)))\s*)))/(x)
t=std::move(std::make_tuple(std::stod(m[1]),0.0));
否则如果(std::regex\u匹配(s,m,std::regex(R)(\s*([-+]?\d*\?\d+(?:[eE][-+]?\d+)))\s*,\s*([-+]?\d*\。\d+(?:[eE][-+]?\d+)\s*))/(x,y)
t=std::move(std::make_tuple(std::stod(m[1]),std::stod(m[2]));
}
返回输入;
}
int main()
{
std::元组t;
std::cout>t;

std::你基本上可以一个字符一个字符地读取和解析。记住,如果输入与你试图读取的内容不匹配,输入缓冲区的状态应该在调用
操作符>
之前保持不变。太好了,比正则表达式简单多了。谢谢你只提了一个问题,因为我不完全理解赋值thr通过>>,这将如何在案例中工作:(x)?我假设输入>>c.x>>定界符>>c.y>>定界符;仅适用于案例(x,y)记住,delimeters是
。在您所指的情况下,else语句通过读取一个数字、一个逗号、一个左括号、一个数字,最后是一个右括号来处理它。真的吗?那太棒了。不过,我必须读更多关于这个主题的内容。这也非常有用,谢谢。我完全忘记了负数,所以我会的调查一下
#include <iostream>
#include <regex>
#include <tuple>

std::istream &operator>> (std::istream &input, std::tuple<double, double> &t)
{
    std::smatch m;
    std::string s;
    if (std::getline(input, s))
    {
        if (std::regex_match(s, m, std::regex(R"(\s*([-+]?\d*\.?\d+(?:[eE][-+]?\d+)?)\s*)"))) //x
            t = std::move(std::make_tuple(std::stod(m[1]), 0.0));
        else if (std::regex_match(s, m, std::regex(R"(\s*\(\s*([-+]?\d*\.?\d+(?:[eE][-+]?\d+)?)\s*\)\s*)"))) //(x)
            t = std::move(std::make_tuple(std::stod(m[1]), 0.0));
        else if (std::regex_match(s, m, std::regex(R"(\s*\(\s*([-+]?\d*\.?\d+(?:[eE][-+]?\d+)?)\s*,\s*([-+]?\d*\.?\d+(?:[eE][-+]?\d+)?)\s*\)\s*)"))) //(x,y)
            t = std::move(std::make_tuple(std::stod(m[1]), std::stod(m[2])));
    }
    return input;
}


int main() 
{
    std::tuple <double, double> t;
    std::cout << "Enter data in format num, (num) or (num1,num2): ";
    std::cin >> t;
    std::cout << "Tuple 0: " << std::get<0>(t) << std::endl;
    std::cout << "Tuple 1: " << std::get<1>(t) << std::endl;

    return 0;

}