【问题标题】:std::ws vs. std::skipws in C++C++ 中的 std::ws 与 std::skipws
【发布时间】:2021-07-12 03:29:59
【问题描述】:

我将从一小段代码开始解释我的问题:

#include <iostream>
#include <string>

int main(){
    int val;
    string s;
    
    std::cin >> val;
    std::getline(std::cin >> std::ws, s);

    std::cout << val << s << std::endl;

    return 0;
}

我了解使用 std::cin &gt;&gt; val 会在缓冲区中留下换行符。
如果之后使用std::getline(std::cin, s),它只会跳过输入,因为它会从cin 捕获那个空格,但是如果我们使用std::getline(std::cin &gt;&gt; std::ws, s),它应该会按预期工作,因为std::ws 将消耗所有前导空格。

现在我的问题是,还有 std::skipws 这样的东西,据我了解 (std::getline(std::cin &gt;&gt; std::skipws, s);) 应该做同样的事情,但这要么是不正确的,因为使用它仍然会跳过输入,或者我是用错了。

  • 为什么std::skipws 在这种情况下不起作用?
  • std::ws 和 std::skipws 有什么区别?
  • 我们什么时候应该使用std::skipws 而不是std::ws?
  • 为什么我们有两个实现相同的东西?两者都应该摆脱空格(根据我目前的理解)

【问题讨论】:

  • 请记住skipws 是默认设置的。您实际上不必选择使用它,而是选择何时显式禁用它。
  • 回复:“它只是跳过输入”——这不是实际发生的情况。正如您所说,它会看到换行符,并终止该读取操作。您键入的输入仍然存在,并且将在后续读取操作中看到。

标签: c++ buffer


【解决方案1】:

std::skipws(和std::noskipws)仅适用于格式化输入,即operator&gt;&gt;,它使用流的sentry类(sentry是实际跳过的那个)。它们对 unformatted 输入没有影响,例如 std::getline(),它不使用 sentry。他们设置/清除流的内部 skipws 标志,该标志对所有后续 格式化 读取保持有效,直到显式更改,该标志不会在每次读取后重置,就像其他一些标志一样。每次在 格式化 读取过程中创建 sentry 时,它都会查看当前的 skipws 标志并采取相应的行动。

std::ws 无条件地从输入流中读取空白。它仅在每次读取的基础上使用。当您有时确实想跳过空格但并非总是如此时,它非常适合与 unformatted 输入一起使用。

【讨论】:

  • 在这种情况下,是否会出现std::skipws 会被std::ws 使用的情况,因为std::ws 将始终/无条件地工作,而std::skipws 只会在格式化输入。
  • @HarshitJindal skipws 仅适用于格式化输入
  • 我明白了。我在上一条评论中不小心写了 unformatted 而不是 formatted。我已经纠正了。那么为什么我们要使用std::skipws 而不是std::ws,如果std::skipws 仅适用于格式化 输入,而std::ws 适用于所有 输入
  • 谢谢,这回答了我问题中的所有要点。将其标记为正确答案
猜你喜欢
  • 2011-05-24
  • 2014-08-07
  • 1970-01-01
  • 2018-06-06
  • 1970-01-01
  • 2021-10-26
  • 1970-01-01
  • 2015-12-03
  • 1970-01-01
相关资源
最近更新 更多