std::ws 与 C++ 中的 std::skipws
std::ws vs. std::skipws in C++
我将从一小段代码开始解释我的问题:
#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 >> val
会在缓冲区中留下换行符。
如果之后使用 std::getline(std::cin, s)
,它会简单地跳过输入,因为它会从 cin
捕获该空白,但如果我们使用 std::getline(std::cin >> std::ws, s)
,它应该像 [=] 一样按预期工作17=] 将消耗所有前导空格。
现在我的问题是,还有 std::skipws
这样的东西,根据我的理解,它应该做同样的事情 (std::getline(std::cin >> std::skipws, s);
),但这要么是不正确的,因为使用它仍然会跳过输入,或者我用错了。
- 为什么
std::skipws
在这种情况下不起作用?
std::ws
和std::skipws
有什么区别?
- 我们什么时候应该使用
std::skipws
而不是 std::ws
?
- 为什么我们对同一事物有 2 个实现?两者都应该去掉空格(根据我目前的理解)
std::skipws
(和std::noskipws
)仅适用于格式化输入,即operator>>
,它使用流的sentry
class(sentry
是执行实际跳过的那个)。它们对 未格式化的 输入没有影响,例如不使用 sentry
的 std::getline()
。它们 set/clear 流的内部 skipws
标志,它在所有后续 格式化 读取中保持有效,直到明确更改,该标志在每次读取后不会重置,就像一些其他标志是。每次在 格式化 读取期间创建 sentry
时,它会查看当前的 skipws
标志并相应地执行操作。
std::ws
无条件地从输入流中读取空白。它仅在每次读取的基础上使用。它非常适合与 未格式化 输入一起使用,当您有时确实想跳过空格时,但并非总是如此。
我将从一小段代码开始解释我的问题:
#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 >> val
会在缓冲区中留下换行符。
如果之后使用 std::getline(std::cin, s)
,它会简单地跳过输入,因为它会从 cin
捕获该空白,但如果我们使用 std::getline(std::cin >> std::ws, s)
,它应该像 [=] 一样按预期工作17=] 将消耗所有前导空格。
现在我的问题是,还有 std::skipws
这样的东西,根据我的理解,它应该做同样的事情 (std::getline(std::cin >> std::skipws, s);
),但这要么是不正确的,因为使用它仍然会跳过输入,或者我用错了。
- 为什么
std::skipws
在这种情况下不起作用? std::ws
和std::skipws
有什么区别?- 我们什么时候应该使用
std::skipws
而不是std::ws
? - 为什么我们对同一事物有 2 个实现?两者都应该去掉空格(根据我目前的理解)
std::skipws
(和std::noskipws
)仅适用于格式化输入,即operator>>
,它使用流的sentry
class(sentry
是执行实际跳过的那个)。它们对 未格式化的 输入没有影响,例如不使用 sentry
的 std::getline()
。它们 set/clear 流的内部 skipws
标志,它在所有后续 格式化 读取中保持有效,直到明确更改,该标志在每次读取后不会重置,就像一些其他标志是。每次在 格式化 读取期间创建 sentry
时,它会查看当前的 skipws
标志并相应地执行操作。
std::ws
无条件地从输入流中读取空白。它仅在每次读取的基础上使用。它非常适合与 未格式化 输入一起使用,当您有时确实想跳过空格时,但并非总是如此。