c++ 重载运算符>>以从字符串创建数组

k3bvogb1  于 2023-01-10  发布在  其他
关注(0)|答案(1)|浏览(84)

我想从一个std::string创建一个std::array
为此,我希望重载operator>>
我有以下测试用例:

std::istream& operator>>(std::istream& is, const std::array<double, 3>& a)
{
    char p1, p2;

    is >> p1;
    // if fail warn the user

    for (unsigned int i = 1; i < a.size(); ++i) 
    {
        // something to ignore/ check if numeric
    }

    is >> p2;
    // if fail warn the user
    
    return is;
}

int main()
{
    std::string a = "[1 2 3]";
    std::array<double, 3> arr;
    std::istringstream iss (a);
    iss >> arr;
    
    return 0;
}

我希望操作员检查字符[]是否在正确的位置,并使用其中的元素构造数组。
我如何检查提取是否成功?我如何检查括号中的字符串是否为数字,如果是,则从中构造数组?
此致

dgtucam1

dgtucam11#

我将添加一个helper类,它检查流中的某个字符,如果存在则将其删除,如果不存在则设置故障位。
示例:

#include <cctype>
#include <istream>

template <char Ch, bool SkipWhitespace = false>
struct eater {
    friend std::istream& operator>>(std::istream& is, eater) {
        if /*constexpr*/ (SkipWhitespace) { // constexpr since C++17
            is >> std::ws;
        }
        if (is.peek() == Ch) // if the expected char is there, remove it
            is.ignore();
        else                 // else set the failbit
            is.setstate(std::ios::failbit);
        return is;
    }
};

它可以这样使用:

std::istream& operator>>(std::istream& is, std::array<double, 3>& a) {
    // use the `eater` class template with `[` and `]` as template parameters:
    return is >> eater<'['>{} >> a[0] >> a[1] >> a[2] >> eater<']'>{};
}

int main() {
    std::string a = "[1 2 3]";
    std::array<double, 3> arr;
    std::istringstream iss (a);
    // iss.exceptions(std::ios::failbit); // if you want exceptions on failure

    if(iss >> arr) {
        std::cout << "success\n";
    } else {
        std::cout << "fail\n";
    }
}

Demo,其中,用作输入中的分隔符。

相关问题