C++ 中的 std::ws 与 std::skipws

Har*_*dal 4 c++ buffer

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

#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;
}
Run Code Online (Sandbox Code Playgroud)

我知道使用std::cin >> val会在缓冲区中留下换行符。
ifstd::getline(std::cin, s)之后使用,它只会跳过输入,因为它将捕获 中的空格cin,但如果我们这样做std::getline(std::cin >> std::ws, s),它应该按预期工作,因为std::ws将会消耗所有前导空格。

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

  • 为什么std::skipws在这种情况下不起作用?
  • std::ws和 和有什么区别std::skipws
  • 我们什么时候应该使用std::skipwsover std::ws
  • 为什么我们对同一件事有两种实现?两者都应该消除空格(根据我目前的理解)

Rem*_*eau 5

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

std::ws无条件从输入流读取空格。它仅用于每次读取。当您有时确实想跳过空格(但并非总是如此)时,它非常适合与未格式化的输入一起使用。