重载运算符>>和<<以便它接受用户定义的对象

时间:2014-11-16 21:37:22

标签: c++ stream overloading

我有一个包含多个字符串(字符串指针)的对象(类myObj)。我想重载>>运算符,以便我可以一次读取多个字符串。

这个重载的运算符函数接受如下语句:

cin>> STR;

cout<< STR;

唯一的问题是,当我填写一系列字符串时,似乎只有第一个字符串在流中得到正确处理。

要插入:

istream &operator>>(istream &is, myObj &obj)
{
    std::string line;

    while (true)
    {
        std::getline(is, line);
        if (not is)
            break;
        obj.add(line);
        is >> line;
    }

    return is; 
}

提取

ostream &operator<<(ostream &os, myObj const &obj)
{
    for(size_t idx = 0; idx != obj.size(); ++idx) 
        os << obj[idx];
    return os;
}

代码编译得很好但是当我输出对象时,只打印第一个字符串而忽略其他字符串。

所以当我提供cin时:

Hi
Stack
Exchange

仅显示嗨。

有谁知道为什么会这样?

提前致谢!

P.S我是Stack Exchange的新手,我正在努力尽可能地制定问题:)

2 个答案:

答案 0 :(得分:1)

你的循环会像那样:

std::getline(is, line);

提取物和商店&#34;嗨&#34;在line中,提取换行符

obj.add(line);

添加&#34;嗨&#34;到obj

is >> line;

提取物和商店&#34; Stack&#34;在line中,不会提取以下换行符

std::getline(is, line);

line中提取并存储空字符串,因为下一个读取字符是换行符

obj.add(line);

添加空字符串&#34;&#34;到obj

is >> line;

提取和存储&#34;交换&#34;在line

std::getline(is, line);

不提取任何内容(输入流的结尾)

if (not is)
    break;

然后流结束,你的循环退出。

结论:您只存储了Hi和一个空字符串

答案 1 :(得分:1)

is >> line在流中放置一个前导换行符,在以下循环中由std::getline()读取。因为std::getline()在找到换行符时会停止输入,所以这会将一个空字符串读入line,因此流会进入错误状态,循环会通过突破它来响应。

似乎不需要最后一次阅读。你可以删除它。

此外,这是一种更加惯用的循环输入方式。这样您就不必检查循环体内流的状态:

for (std::string line; std::getline(is, line); )
{
    obj.add(line);
}

由于每行只有一个令牌,因此您可以使用格式化的提取器:

for (std::string word; is >> word; )
{
    obj.add(word);
}