Персонажи, извлеченные istream >> double

Образец кодав Колиру:

#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";
}

Я зачитываю здесь N3337 (предположительно, это то же самое, что и C ++ 11). В [istream.formatted.arithmetic] мы имеем (перефразировано):

operator>>(double& val);

Как и в случае вставок, эти экстракторы зависят от объекта локали num_get <> (22.4.2.1) для выполнения анализа данных входного потока. Эти экстракторы ведут себя как отформатированные функции ввода (как описано в 27.7.2.2.1). После того, как часовой объект создан, преобразование происходит так, как если бы оно выполнялось следующим фрагментом кода:

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);

Глядя на 22.4.2.1:

Детали этой операции происходят в три этапа
- Этап 1: определить спецификатор конверсии
- Этап 2: извлечение символов из in и определение соответствующего значения символа для формата, ожидаемого согласно спецификации преобразования, определенной на этапе 1.
- Этап 3: результаты магазина

В описании Стадии 2 я слишком долго вставляю все это сюда. Однако в нем четко сказано, что все символы должны быть извлечены до попытки преобразования; и далее, что именно следующие символы должны быть извлечены:

любой из0123456789abcdefxABCDEFX+-Локальdecimal_point()Локальthousands_sep()

Наконец, правила для Стадии 3 включают в себя:

- Для значения с плавающей точкой функцияstrtold.

Числовое значение, которое будет сохранено, может быть одним из:

- ноль, если функция преобразования не может преобразовать все поле.

Кажется, все это четко указывает на то, что вывод моего кода должен быть0, 'ipxngh', Однако на самом деле он выводит что-то еще.

Это ошибка компилятора / библиотеки? Есть ли какое-либо положение, которое я пропускаю, чтобы локаль изменила поведение этапа 2? (ВДругой вопрос кто-то опубликовал пример системы, которая на самом деле извлекает символы, но также извлекаетipxn которых нет в списке, указанном в N3337).

Обновить

Как указывает Perreal, этот текст из Стадии 2 актуален:

Если сброс - это правда, то, если ''. 'Еще не накоплено, то позиция персонажа запоминается, но в противном случае персонаж игнорируется. В противном случае, если ’.’ Уже накоплено, персонаж отбрасывается и этап 2 завершается. Если он не отбрасывается, выполняется проверка, чтобы определить,c допускается в качестве следующего символа поля ввода спецификатора преобразования, возвращаемого этапом 1. Если это так, он накапливается.

Если символ либо отбрасывается, либо накапливается, то значение in повышается с помощью ++ in, и обработка возвращается к началу этапа 2.

Таким образом, этап 2 может завершиться, если символ находится в списке разрешенных символов, но не является допустимым символом для%g, Это не говорит точно, но, вероятно, это относится к определениюfscanf от C99, что позволяет:

непустая последовательность десятичных цифр, необязательно содержащая символ десятичной точки, затем необязательная часть экспоненты, как определено в 6.4.4.2;0x или 0X, затем непустая последовательность шестнадцатеричных цифр, необязательно содержащая символ десятичной точки, затем необязательная двоичная экспоненциальная часть, как определено в 6.4.4.2;INF или INFINITY, игнорируя регистрNAN или NAN (n-char-sequence opt), игнорируя регистр в части NAN, где:

а также

В отличие от локали "C", могут быть приняты дополнительные формы предметной последовательности, специфичные для локали.

Итак, на самом деле вывод Coliru правильный; и на самом деле обработкадолжен попытаться проверить последовательность символов, извлеченных до допустимого ввода в%g, извлекая каждый символ.

Следующий вопрос: разрешено ли, как в ветке, на которую я ссылался ранее, принятьi , n, p и т.д. на этапе 2?

Это допустимые символы для%g однако они не находятся в списке атомов, которые Стадии 2 разрешено читать (т.е.c == 0 для моей последней цитаты, поэтому персонаж не сбрасывается и не накапливается).

Ответы на вопрос(2)

Ваш ответ на вопрос