Sample code at Coliru:
#include
#include
#include
int main()
{
double d; std::string s;
std::istrin
This is a mess because it's likely that neither gcc/libstdc++'s nor clang/libc++'s implementation is conforming. It's unclear "a check is made to determine if c is allowed as the next character of an input field of the conversion specifier returned by Stage 1" means, but I think that the use of the phrase "next character" indicates that check should be context-sensitive (i.e., dependent on the characters that have already been accumulated), and so an attempt to parse, e.g., "21abc"
, should stop when 'a'
is encountered. This is consistent with the discussion in LWG issue 2041, which added this sentence back to the standard after it had been deleted during the drafting of C++11. libc++'s failure to do so is bug 17782.
libstdc++, on the other hand, refuses to parse "0xABp-4"
past the 0
, which is actually clearly nonconforming based on the standard (it should parse "0xAB"
as a hexfloat, as clearly allowed by the C99 fscanf
specification for %g
).
The accepting of i
, p
, and n
is not allowed by the standard. See LWG issue 2381.
The standard describes the processing very precisely - it must be done "as if" by the specified code fragment, which does not accept those characters. Compare the resolution of LWG issue 221, in which they added x
and X
to the list of characters because num_get
as then-described won't otherwise parse 0x
for integer inputs.
Clang/libc++ accepts "inf" and "nan" along with hexfloats but not "infinity" as an extension. See bug 19611.
At the end of stage 2, it says:
If it is not discarded, then a check is made to determine if c is allowed as the next character of an input field of the conversion specifier returned by Stage 1. If so, it is accumulated.
If the character is either discarded or accumulated then in is advanced by ++in and processing returns to the beginning of stage 2.
So perhaps a
is not allowed in the %g
specifier and it is not accumulated or ignored.