簡體   English   中英

C ++從istream指定輸入並對其進行測試

[英]C++ Specify input from istream and test it

我有一個基本上表示一個元組(雙倍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 :: cin >>“(10.2,5.5)”
還是我需要從文件中讀取內容進行測試?

編輯:給出的答案確實解決了這個問題,但是我想添加一種測試它的方法,因為它可能是使用我以外的人:

tuple x(6,2);
stringstream ss;
ss << x;
ASSERT_EQUALS(ss.str(), "(6,2)\n");

對於這樣的簡單輸入任務,正則表達式將是不必要的。 這是我的方法,無需解析任何有效輸入,只需解析即可:

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;

} 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM