Caracteres extraídos por istream >> double

Código de amostrana Coliru:

#include <iostream>
#include <sstream>
#include <string>

int main()
{
    double d; std::string s;

    std::istringstream iss("234cdefipxngh");
    iss >> d;
    iss.clear();
    iss >> s;
    std::cout << d << ", '" << s << "'\n";
}

Estou lendo o N3337 aqui (presumivelmente é o mesmo que o C ++ 11). Em [istream.formatted.arithmetic], temos (parafraseado):

operator>>(double& val);

Como no caso dos insersores, esses extratores dependem do objeto num_get <> (22.4.2.1) da localidade para realizar a análise dos dados do fluxo de entrada. Esses extratores se comportam como funções de entrada formatadas (conforme descrito em 27.7.2.2.1). Após a construção de um objeto de sentinela, a conversão ocorre como se fosse realizada pelo seguinte fragmento de código:

typedef num_get< charT,istreambuf_iterator<charT,traits> > numget;
iostate err = iostate::goodbit;
use_facet< numget >(loc).get(*this, 0, *this, err, val);
setstate(err);

Olhando para 22.4.2.1:

Os detalhes desta operação ocorrem em três etapas
- Etapa 1: determinar um especificador de conversão
- Estágio 2: extraia os caracteres de in e determine um valor de char correspondente para o formato esperado pela especificação de conversão determinada no estágio 1.
- Etapa 3: armazenar resultados

Na descrição do Estágio 2, é muito longo para eu colar a coisa toda aqui. No entanto, diz claramente que todos os caracteres devem ser extraídos antes da tentativa de conversão; e ainda que exatamente os seguintes caracteres devem ser extraídos:

qualquer um0123456789abcdefxABCDEFX+-O localdecimal_point()O localthousands_sep()

Por fim, as regras para o Estágio 3 incluem:

- Para um valor de ponto flutuante, a funçãostrtold.

O valor numérico a ser armazenado pode ser um dos seguintes:

- zero, se a função de conversão falhar ao converter o campo inteiro.

Tudo isso parece especificar claramente que a saída do meu código deve ser0, 'ipxngh'. No entanto, ele realmente gera outra coisa.

Isso é um bug do compilador / biblioteca? Existe alguma disposição que estou ignorando para uma localidade para alterar o comportamento do Estágio 2? (Nooutra pergunta alguém postou um exemplo de sistema que realmente extrai os caracteres, mas também extraiipxn que não estão na lista especificada em N3337).

Atualizar

Como apontado por perreal, este texto do estágio 2 é relevante:

Se o descarte for verdadeiro, se '' ainda não tiver sido acumulado, a posição do personagem será lembrada, mas o personagem será ignorado. Caso contrário, se '' já tiver sido acumulado, o personagem será descartado e o estágio 2 será encerrado. Se não for descartado, é feita uma verificação para determinar sec é permitido como o próximo caractere de um campo de entrada do especificador de conversão retornado pelo Estágio 1. Nesse caso, ele é acumulado.

Se o caractere for descartado ou acumulado, o in será avançado por ++ in e o processamento retornará ao início do estágio 2.

Portanto, o estágio 2 pode terminar se o personagem estiver na lista de caracteres permitidos, mas não for um caractere válido para%g. Não diz exatamente, mas presumivelmente isso se refere à definição defscanf do C99, que permite:

uma sequência não vazia de dígitos decimais opcionalmente contendo um caractere de ponto decimal e, em seguida, uma parte opcional do expoente, conforme definido em 6.4.4.2;um 0x ou 0X, então uma sequência não vazia de dígitos hexadecimais opcionalmente contendo um caractere de ponto decimal e, em seguida, uma parte opcional do expoente binário, conforme definido em 6.4.4.2;INF ou INFINITY, ignorando maiúsculas e minúsculasNAN ou NAN (opção n-char-sequence), ignorando o caso na parte NAN, em que:

e também

Em outro local que não o "C", podem ser aceitas formas adicionais de sequência de assunto específicas do local.

Então, na verdade, a saída do Coliru está correta; e de fato o processamentodevo tentativa de validar a sequência de caracteres extraídos até uma entrada válida para%g, ao extrair cada caractere.

Próxima pergunta: é permitido, como no tópico ao qual vinculei anteriormente, aceitari , n, p etc no estágio 2?

Esses são caracteres válidos para%g , no entanto, eles não estão na lista de átomos que a Etapa 2 pode ler (ou seja,c == 0 para minha última citação, para que o personagem não seja descartado nem acumulado).

questionAnswers(2)

yourAnswerToTheQuestion