【问题标题】:Why does cin command leaves a '\n' in the buffer?为什么 cin 命令在缓冲区中留下一个 '\n'?
【发布时间】:2015-01-23 12:14:10
【问题描述】:

这与:cin and getline skipping input 有关,但他们没有回答为什么会发生这种情况,只回答如何解决它。

为什么cin 在缓冲区中留下一个 '\n' 而只有 cin.getline 接受它?

例如:

cin >> foo;
cin >> bar;//No problem
cin >> baz;//No problem.

但是cin.getline

cin >> foo;
cin.getline(bar,100);//will take the '\n'

那么为什么 cin 不会发生这种情况,而 cin.getline 会发生这种情况?

【问题讨论】:

  • foobarbaz 的类型是什么?你试过玩skipws吗?
  • cin 不是命令。它是std::ostream 类型的对象。相反,>>std::ostream::operator>>,即。 e.操作员(仍然不是“命令”)。它将换行符留在缓冲区中,因为 C++ 标准规定此运​​算符必须将换行符留在缓冲区中。 std::getline() 不会将它留在缓冲区中,因为规范说它必须使用换行符。这就是为什么。
  • 每个人都知道为 C++ 标准库贡献 STL 的人的名字。没有人知道是谁创建了 iostream。如果我是 Jerry Schwarz,那么我也更愿意保持这种状态:)
  • @HansPassant 你是认真的吗?
  • 好吧,去看看 lolz,但有一个真理的核心。我认为没有任何 C++ 程序员对 iostream 的结果印象深刻。这肯定是有原因的,Schwartz 必须使用早期设计,这些设计可以追溯到世界仍然使用 C 和 C++ 还没有异常和多重继承的时代。很难猜出他必须使用什么样的约束才能避免破坏大量现有代码。你的问题有什么问题,只有施瓦茨能准确回答。

标签: c++ syntax


【解决方案1】:

因为,当你说getline 时,你说你想得到一行……一行是以\n 结尾的字符串,结尾是它不可或缺的一部分。

当你说cin >> something 时,你想得到精确的something,仅此而已。结束行标记不是其中的一部分,因此不会被消耗。除非你有一个特殊的 line 类型,但是标准库中没有这样的东西。

虽然没有引用标准,这可能被视为意见,但这是其背后的逻辑。 它们有不同的语义。还有另一个区别getline 用作unformatted input,而operator>> 用作formatted input。我强烈建议阅读这些链接以了解差异。这也说明它们在语义上是不同的。

另一个答案,更好与否是值得商榷的,是引用标准,我敢肯定地说,getline 的行为方式,以及operator>> 对不同类型的行为方式,并且说,它的工作原理是这样的,因为标准这么说。这会很好,因为该标准绝对定义了事物的工作方式,并且可以任意进行......而且它很少解释设计背后的动机和逻辑。

【讨论】:

  • 所以cin'\n' 留在缓冲区中?在几个cins 之后缓冲区中可以有几个'\n' 字符吗?
  • 我不确定我是否跟随。你问这个:如果标准输入缓冲区是“foo\n\n\nbar\n”并且会做cin >> text;然后cin >> text2;你会得到什么?
  • @rubenvb 哦,是的,它是一个函数,我太聪明了,我不确定当你在带有 windows 结尾的 windows 上执行 getline 时会得到什么。
  • 解释得很好。逻辑是在这里理解的重要内容。
【解决方案2】:

您不是在比较 cincin.getline,而是比较 cin.operator>>cin.getline,而这正是定义这些函数的目的。 “为什么”这个问题的答案是“根据定义”。如果你想要理由,我不能给你。

cin.getline 读取并使用,直到输入换行符 \ncin.operator>> 不使用此换行符。后者执行格式化输入,跳过前导空格,直到它正在读取的对象的末尾(在你的情况下,无论foo 是)“停止”(如果fooint,当字符不是一个号码)。换行符是从输入行中消耗数字时剩下的内容。 cin.getline 读取一行,并根据定义使用换行符。

确保始终检查每个流操作的错误:

if(cin >> foo)

if(std::getline(cin, some_string))

请注意,我使用 std::getline 而不是流的成员,因为这样就不需要任何幻数(代码中的 100)。

【讨论】:

  • 为什么要将它们放在if() 中检查错误?怎么可能是 0 或 1?
  • @kuhaku 是 operator>> (返回对流对象的引用)结果的隐式(或显式,在 C++11 中)转换为 bool。参见例如here
  • 我明白了,非常好用。
猜你喜欢
  • 2011-05-10
  • 1970-01-01
  • 1970-01-01
  • 2020-07-23
  • 1970-01-01
  • 2014-12-03
  • 1970-01-01
  • 1970-01-01
  • 2020-12-09
相关资源
最近更新 更多