1

我有一个以下容器,我想将其存储在一个文件中:

std::vector< std::vector< Point > > m_vPoints;

Pointoperator<<()是一个定义了和的基本结构operator>>()

文件格式为:

point0_0 point0_1 point0_2 ... <-- points from m_vPoints[0]
point1_0 point1_1 ...          <-- points from m_vPoints[1]
...

点元素由 分隔',',点由' '例如:

-5,4 6,12 -7,32 ...
12,0 -3,4 ...

我设法生成了这样一个文件:

std::ostream& operator<<(std::ostream &o, ...)
{
    for(auto it=m_vPoints.begin(); it!=m_vPoints.end(); ++it)
    {
        copy(it->begin(), it->end(), std::ostream_iterator<Point>(o," "));
        o << endl;
    }
    return o;
}

它工作正常。然而,问题在于阅读。当我尝试以下操作时:

std::istream& operator>>(std::istream &is, ...)
{
    int numberOfRows; // assume it is known and valid
    m_vPoints.resize(numberOfRows);
    for(int i=0; i<numberOfRows; i++)
    {
        copy(std::istream_iterator<Point>(is), std::istream_iterator<Point>(), std::back_inserter(m_vPoints[i]));
    }
    return is;
}

所有行的所有点都被读入m_vPoints[0]. 它看起来像std::istream_iterator<Point>()忽略std::endl。使用is >> noskipws将不起作用,因为我仍然想跳过分隔各个点的空格。所以基本上,问题是从 istream 复制,但不是直到达到流尾,而是直到行尾。我在网上看到的示例以cin某种方式设法解析一行,忽略空格字符,但正确地以std::endlor结尾'\n'

我也想避免getline(),因为那时我必须将每一行复制到一个字符串,然后解析该字符串。相反,我想将行i直接复制到容器m_vPoints[i]

4

1 回答 1

5

逐行阅读:

std::istream& operator>>(std::istream &is,
                         std::vector<std::vector<Point>>& points)
{
    using namespace std;
    using point_itr = istream_iterator<Point>;
    string line;
    while( getline(is, line) ) // read line by line
    {
        // iterate points from istringstream into new line vector
        istringstream line_in{ line };
        points.emplace_back(
            make_move_iterator(point_itr{ line_in }),
            make_move_iterator(point_itr{}) );
    }
    return is;
}

编辑

这是规范的解决方案。

我还想避免 getline(),因为我必须将每一行复制到一个字符串,然后解析该字符串。相反,我想将第 i 行直接复制到容器 m_vPoints[i]

您是否有理由要避免使用 std::getline?

if(is.peek() == '\n')阅读每一点后,您可以在代码中使用。这将使您的代码(更)复杂,因为您将不再能够直接从迭代器复制,并且执行此操作的实际代码会更复杂(您还必须手动处理输入流错误状态)。

于 2015-08-12T11:09:26.573 回答