C ++中的noskipws演示 [英] Demonstration of noskipws in C++
问题描述
我正在尝试使用C ++的noskipws机械手,并编写了以下代码.
#include <iostream>
#include <sstream>
#include <string>
using namespace std;
int main()
{
string first, middle, last;
istringstream("G B Shaw") >> first >> middle >> last;
cout << "Default behavior: First Name = " << first << ", Middle Name = " << middle << ", Last Name = " << last << '\n';
istringstream("G B Shaw") >> noskipws >> first >> middle >> last;
cout << "noskipws behavior: First Name = " << first << ", Middle Name = " << middle << ", Last Name = " << last << '\n';
}
我希望得到以下输出:
预期产量
Default behavior: First Name = G, Middle Name = B, Last Name = Shaw
noskipws behavior: First Name = G, Middle Name = , Last Name = B
输出
Default behavior: First Name = G, Middle Name = B, Last Name = Shaw
noskipws behavior: First Name = G, Middle Name = , Last Name = Shaw
我修改了此代码,使其可用于此类字符,并且效果很好.
#include <iostream>
#include <sstream>
#include <string>
using namespace std;
int main()
{
char first, middle, last;
istringstream("G B S") >> first >> middle >> last;
cout << "Default behavior: First Name = " << first << ", Middle Name = " << middle << ", Last Name = " << last << '\n';
istringstream("G B S") >> noskipws >> first >> middle >> last;
cout << "noskipws behavior: First Name = " << first << ", Middle Name = " << middle << ", Last Name = " << last << '\n';
}
我知道cin是如何工作的,我无法弄清楚为什么在string
情况下它会以这种方式工作.
std::istringstream("G B S") >> std::noskipws >> first >> middle >> last;
对字符串进行提取时,首先清除字符串并将字符插入其缓冲区.
21.4.8.9插入器和提取器
template<class charT, class traits, class Allocator> basic_istream<charT, traits>& operator>>(basic_istream<charT, traits>& is, basic_string<charT, traits, Allocator>& str);
效果:表现为格式化的输入函数(27.7.2.2.1).构造哨兵对象后,如果哨兵转换为
true
,则调用str.erase()
,然后从is
中提取字符,并将其追加到str
中,就像通过调用str.append(1, c).
[. ..]
第一次读取会将字符串"G"
提取到first
中.对于第二次提取,由于设置了std::noskipws
格式标志,因此无法清除任何前导空格,因此不会提取任何内容.因此,将清除字符串,然后由于未放入任何字符而导致提取失败.这是上面子句的延续:
21.4.8.9插入器和提取器(续)
[...]提取并附加字符,直到发生以下任何一种情况:
n
个字符被存储;文件结尾出现在输入序列上;
isspace(c, is.getloc())
对于下一个可用输入为true 字符c
.
当流确定提取失败时,将std::ios_base::failbit
设置为流状态,指示错误.
从这时开始,任何和所有的I/O尝试都将失败,除非清除了流状态.如果没有清除所有错误的流状态,提取器将无法运行,并且将无法运行.这意味着对last
的提取不会执行任何操作,并且会保留上一次提取(没有std::noskipws
的提取)所具有的值,因为流没有清除了字符串./p>
关于使用char
起作用的原因:在C或C ++中,字符没有格式要求.任何字符都可以提取到char
类型的对象中,这就是尽管设置了std::noskipws
还是看到正确输出的原因:
27.7.2.2.3/1 [istream ::提取器]
template<class charT, class traits> basic_istream<charT, traits>& operator>>(basic_istream<charT, traits>& in, charT& c);
效果:行为类似于in的格式化输入成员(如27.7.2.2.1中所述).构造哨兵对象后,如果可用,则从
in
中提取一个字符,并将其存储在c
中. .否则,该函数将调用in.setstate(failbit)
.
提取器的语义会将字符存储在其操作数(如果可用)中.它不限制空格(甚至不限制EOF字符!).它将像正常字符一样提取它.
I was trying out the noskipws manipulator in C++ and I wrote following code.
#include <iostream>
#include <sstream>
#include <string>
using namespace std;
int main()
{
string first, middle, last;
istringstream("G B Shaw") >> first >> middle >> last;
cout << "Default behavior: First Name = " << first << ", Middle Name = " << middle << ", Last Name = " << last << '\n';
istringstream("G B Shaw") >> noskipws >> first >> middle >> last;
cout << "noskipws behavior: First Name = " << first << ", Middle Name = " << middle << ", Last Name = " << last << '\n';
}
I expect the following output:
Expected Output
Default behavior: First Name = G, Middle Name = B, Last Name = Shaw
noskipws behavior: First Name = G, Middle Name = , Last Name = B
Output
Default behavior: First Name = G, Middle Name = B, Last Name = Shaw
noskipws behavior: First Name = G, Middle Name = , Last Name = Shaw
I modified this code to make it work for chars like this and it works perfectly fine.
#include <iostream>
#include <sstream>
#include <string>
using namespace std;
int main()
{
char first, middle, last;
istringstream("G B S") >> first >> middle >> last;
cout << "Default behavior: First Name = " << first << ", Middle Name = " << middle << ", Last Name = " << last << '\n';
istringstream("G B S") >> noskipws >> first >> middle >> last;
cout << "noskipws behavior: First Name = " << first << ", Middle Name = " << middle << ", Last Name = " << last << '\n';
}
I know how cin works and I wasn't able to figure out why it works this way in case of string
.
std::istringstream("G B S") >> std::noskipws >> first >> middle >> last;
When an extraction is performed on strings, the string is first cleared and characters are inserted into its buffer.
21.4.8.9 Inserters and extractors
template<class charT, class traits, class Allocator> basic_istream<charT, traits>& operator>>(basic_istream<charT, traits>& is, basic_string<charT, traits, Allocator>& str);
Effects: Behaves as a formatted input function (27.7.2.2.1). After constructing a sentry object, if the sentry converts to
true
, callsstr.erase()
and then extracts characters fromis
and appends them tostr
as if by callingstr.append(1, c).
[...]
The first read will extract the string "G"
into first
. For the second extraction, nothing will be extracted because the std::noskipws
format flag is set, disabling the clearing of leading whitespace. Because of this, the string is cleared and then the extraction fails because no characters were put in. Here is the continuation of the above clause:
21.4.8.9 Inserters and extractors (Cont.)
[...] Characters are extracted and appended until any of the following occurs:
n
characters are stored;end-of-file occurs on the input sequence;
isspace(c, is.getloc())
is true for the next available input characterc
.
When the stream determines a failed extraction the std::ios_base::failbit
is set in the stream state indicating an error.
From this point on any and all attempts at I/O will fail unless the stream state is cleared. The extractor becomes inoperable and it will not run given a stream state not cleared of all its errors. This means that the extraction into last
doesn't do anything and it retains the value it had at the previous extraction (the one without std::noskipws
) because the stream did not clear the string.
As for the reason why using char
works: Characters have no formatting requirements in C or C++. Any and all characters can be extracted into a object of type char
, which is the reason why you're seeing the correct output despite std::noskipws
being set:
27.7.2.2.3/1 [istream::extractors]
template<class charT, class traits> basic_istream<charT, traits>& operator>>(basic_istream<charT, traits>& in, charT& c);
Effects: Behaves like a formatted input member (as described in 27.7.2.2.1) of in. After a sentry object is constructed a character is extracted from
in
, if one is available, and stored inc
. Otherwise, the function callsin.setstate(failbit)
.
The semantics for the extractor will store a character into its operand if one is available. It doesn't delimit upon whitespace (or even the EOF character!). It will extract it just like a normal character.
这篇关于C ++中的noskipws演示的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!