【问题标题】:Overloading operator >> and << so that it accepts user-defined object重载运算符 >> 和 << 以便它接受用户定义的对象
【发布时间】:2014-11-17 16:49:55
【问题描述】:

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

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

cin >> str;

cout

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

插入:

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;
}

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

所以当我向 cin 提供:

Hi
Stack
Exchange

只会显示 Hi。

有人知道为什么会这样吗?

提前致谢!

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

【问题讨论】:

  • 为什么要在循环中使用std::getlineis &gt;&gt; line?这将提取数据两次,因此每两行丢失一个
  • 谢谢!这实际上解决了它!我仔细看了一遍=/
  • 那么请接受完整的答案:)
  • 为什么不while (std::getline(is, line)) {}

标签: c++ stream overloading


【解决方案1】:

你的循环会这样工作:

std::getline(is, line);

提取“Hi”并将其存储在line 中,提取换行符

obj.add(line);

obj 中添加“嗨”

is >> line;

line 中提取和存储“堆栈”,不提取以下换行符

std::getline(is, line);

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

obj.add(line);

将空字符串“”添加到obj

is >> line;

提取“Exchange”并将其存储在line

std::getline(is, line);

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

if (not is)
    break;

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

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

【讨论】:

    【解决方案2】:

    is &gt;&gt; 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);
    }
    

    【讨论】:

    • 这些是 for-loop C++14 吗?我以前没见过……你能解释一下吗?它如何终止循环?
    • 我改编了这个实现,它使用 C++11 编译,所以它一直是 C++14 之前存在的一个特性。
    • @0x382fd442 这不是一个特殊的 for 循环。首先,for 循环的所有三个语句都是可选的。第一个语句用于变量声明,第二个是循环停止的条件,第三个是在循环结束时运行的语句。 std::getline()operator&gt;&gt;() 之类的函数返回对流的引用,该引用具有 operator bool() 方法,该方法返回一个指示成功或失败的布尔值。
    • @0x499602D2 好吧,我已经尝试过了,但是当我将cin 传递到循环中时,它似乎效果不佳。仅当我键入 时它不会终止它。
    • @0x382fd442 代码是否与此处显示的相同?这可能是因为operator&gt;&gt;() 丢弃了前导空格。换行符是一个空白字符。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-04-04
    • 1970-01-01
    • 2011-01-29
    • 2019-02-01
    • 1970-01-01
    • 2014-07-24
    • 1970-01-01
    相关资源
    最近更新 更多