25 Localization library [localization]

25.4 Standard locale categories [locale.categories]

25.4.2 The numeric category [category.numeric]

25.4.2.1 Class template num_­get [locale.num.get]

namespace std {
  template <class charT, class InputIterator = istreambuf_iterator<charT>>
    class num_get : public locale::facet {
    public:
      using char_type = charT;
      using iter_type = InputIterator;

      explicit num_get(size_t refs = 0);

      iter_type get(iter_type in, iter_type end, ios_base&,
                    ios_base::iostate& err, bool& v) const;
      iter_type get(iter_type in, iter_type end, ios_base&,
                    ios_base::iostate& err, long& v) const;
      iter_type get(iter_type in, iter_type end, ios_base&,
                    ios_base::iostate& err, long long& v) const;
      iter_type get(iter_type in, iter_type end, ios_base&,
                    ios_base::iostate& err, unsigned short& v) const;
      iter_type get(iter_type in, iter_type end, ios_base&,
                    ios_base::iostate& err, unsigned int& v) const;
      iter_type get(iter_type in, iter_type end, ios_base&,
                    ios_base::iostate& err, unsigned long& v) const;
      iter_type get(iter_type in, iter_type end, ios_base&,
                    ios_base::iostate& err, unsigned long long& v) const;
      iter_type get(iter_type in, iter_type end, ios_base&,
                    ios_base::iostate& err, float& v) const;
      iter_type get(iter_type in, iter_type end, ios_base&,
                    ios_base::iostate& err, double& v) const;
      iter_type get(iter_type in, iter_type end, ios_base&,
                    ios_base::iostate& err, long double& v) const;
      iter_type get(iter_type in, iter_type end, ios_base&,
                    ios_base::iostate& err, void*& v) const;

      static locale::id id;

    protected:
      ~num_get();
      virtual iter_type do_get(iter_type, iter_type, ios_base&,
                               ios_base::iostate& err, bool& v) const;
      virtual iter_type do_get(iter_type, iter_type, ios_base&,
                               ios_base::iostate& err, long& v) const;
      virtual iter_type do_get(iter_type, iter_type, ios_base&,
                               ios_base::iostate& err, long long& v) const;
      virtual iter_type do_get(iter_type, iter_type, ios_base&,
                               ios_base::iostate& err, unsigned short& v) const;
      virtual iter_type do_get(iter_type, iter_type, ios_base&,
                               ios_base::iostate& err, unsigned int& v) const;
      virtual iter_type do_get(iter_type, iter_type, ios_base&,
                               ios_base::iostate& err, unsigned long& v) const;
      virtual iter_type do_get(iter_type, iter_type, ios_base&,
                               ios_base::iostate& err, unsigned long long& v) const;
      virtual iter_type do_get(iter_type, iter_type, ios_base&,
                               ios_base::iostate& err, float& v) const;
      virtual iter_type do_get(iter_type, iter_type, ios_base&,
                               ios_base::iostate& err, double& v) const;
      virtual iter_type do_get(iter_type, iter_type, ios_base&,
                               ios_base::iostate& err, long double& v) const;
      virtual iter_type do_get(iter_type, iter_type, ios_base&,
                               ios_base::iostate& err, void*& v) const;
    };
}

Фасет num_­get используется для синтаксического анализа числовых значений из входной последовательности, такой как istream.

25.4.2.1.1 num_­get members [facet.num.get.members]

iter_type get(iter_type in, iter_type end, ios_base& str, ios_base::iostate& err, bool& val) const; iter_type get(iter_type in, iter_type end, ios_base& str, ios_base::iostate& err, long& val) const; iter_type get(iter_type in, iter_type end, ios_base& str, ios_base::iostate& err, long long& val) const; iter_type get(iter_type in, iter_type end, ios_base& str, ios_base::iostate& err, unsigned short& val) const; iter_type get(iter_type in, iter_type end, ios_base& str, ios_base::iostate& err, unsigned int& val) const; iter_type get(iter_type in, iter_type end, ios_base& str, ios_base::iostate& err, unsigned long& val) const; iter_type get(iter_type in, iter_type end, ios_base& str, ios_base::iostate& err, unsigned long long& val) const; iter_type get(iter_type in, iter_type end, ios_base& str, ios_base::iostate& err, float& val) const; iter_type get(iter_type in, iter_type end, ios_base& str, ios_base::iostate& err, double& val) const; iter_type get(iter_type in, iter_type end, ios_base& str, ios_base::iostate& err, long double& val) const; iter_type get(iter_type in, iter_type end, ios_base& str, ios_base::iostate& err, void*& val) const;

Returns: do_­get(in, end, str, err, val).

25.4.2.1.2 num_­get virtual functions [facet.num.get.virtuals]

iter_type do_get(iter_type in, iter_type end, ios_base& str, ios_base::iostate& err, long& val) const; iter_type do_get(iter_type in, iter_type end, ios_base& str, ios_base::iostate& err, long long& val) const; iter_type do_get(iter_type in, iter_type end, ios_base& str, ios_base::iostate& err, unsigned short& val) const; iter_type do_get(iter_type in, iter_type end, ios_base& str, ios_base::iostate& err, unsigned int& val) const; iter_type do_get(iter_type in, iter_type end, ios_base& str, ios_base::iostate& err, unsigned long& val) const; iter_type do_get(iter_type in, iter_type end, ios_base& str, ios_base::iostate& err, unsigned long long& val) const; iter_type do_get(iter_type in, iter_type end, ios_base& str, ios_base::iostate& err, float& val) const; iter_type do_get(iter_type in, iter_type end, ios_base& str, ios_base::iostate& err, double& val) const; iter_type do_get(iter_type in, iter_type end, ios_base& str, ios_base::iostate& err, long double& val) const; iter_type do_get(iter_type in, iter_type end, ios_base& str, ios_base::iostate& err, void*& val) const;

Effects: Читает символыin, интерпретируя их в соответствии с str.flags(), use_­facet<ctype<​charT>>(loc)и use_­facet<numpunct<charT>>(loc), где loc это str.getloc().

Детали этой операции происходят в три этапа.

  • Этап 1. Определение спецификатора преобразования

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

  • Этап 3: сохранение результатов

Подробности этапов представлены ниже.

  • Этап 1: функция инициализирует локальные переменные через

    fmtflags flags = str.flags();
    fmtflags basefield = (flags & ios_base::basefield);
    fmtflags uppercase = (flags & ios_base::uppercase);
    fmtflags boolalpha = (flags & ios_base::boolalpha);

    Для преобразования в целочисленный тип функция определяет спецификатор целочисленного преобразования, как указано в таблице73. Стол заказан. То есть применяется первая строка, для которой выполнено условие.

    Таблица73 - Целочисленные преобразования
    Состояниеstdio эквивалент
    basefield == oct %o
    basefield == hex %X
    basefield == 0 %i
    signed интегральный тип %d
    unsigned интегральный тип %u

    Для преобразований в плавающий тип спецификатором является %g.

    Для преобразований void* в спецификатор есть %p.

    При необходимости в спецификацию преобразования добавляется модификатор длины, как указано в таблице74.

    Таблица74 - модификатор длины
    Тип Модификатор длины
    short h
    unsigned short h
    long l
    unsigned long l
    long long ll
    unsigned long long ll
    double l
    long double L
  • Этап 2: Если in == end затем этап 2 завершается. В противном случае a charT берется из,in и локальные переменные инициализируются, как если бы

    char_type ct = *in;
    char c = src[find(atoms, atoms + sizeof(src) - 1, ct) - atoms];
    if (ct == use_facet<numpunct<charT>>(loc).decimal_point())
    c = '.';
    bool discard =
      ct == use_facet<numpunct<charT>>(loc).thousands_sep()
      && use_facet<numpunct<charT>>(loc).grouping().length() != 0;

    где значения src и atoms определяются как если бы:

    static const char src[] = "0123456789abcdefxABCDEFX+-";
    char_type atoms[sizeof(src)];
    use_facet<ctype<charT>>(loc).widen(src, src + sizeof(src), atoms);

    для этого значения loc.

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

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

  • Этап 3: последовательностьchars, накопленная на этапе 2 (поле), преобразуется в числовое значение по правилам одной из функций, объявленных в заголовке<cstdlib>:

    • Для целого числа со знаком функцияstrtoll.

    • Для целочисленного значения без знака функцияstrtoull.

    • Дляfloat значения функцияstrtof.

    • Дляdouble значения функцияstrtod.

    • Дляlong double значения функцияstrtold.

    Сохраняемое числовое значение может быть одним из:

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

    • наиболее положительное (или отрицательное) представимое значение, если поле, которое нужно преобразовать в целочисленный тип со знаком, представляет собой слишком большое положительное (или отрицательное) значение для представления вval.

    • наиболее положительное представимое значение, если поле, которое нужно преобразовать в беззнаковый целочисленный тип, представляет значение, которое не может быть представлено вval.

    • преобразованное значение, в противном случае.

    Результирующее числовое значение сохраняется вval. Если функция преобразования не преобразует все поле или если поле представляет значение вне диапазона представимых значений, ios_­base​::​failbit присваиваетсяerr.

Группировка цифр проверяется. Таким образом, позиции отброшенных разделителей проверяются на соответствие use_­facet<numpunct<charT>>(loc).grouping(). Если они не согласуются, то ios_­base​::​failbit назначаетсяerr.

В любом случае, если обработка этапа 2 была прервана тестом, in == end то err |= ios_­base​::​eofbit выполняется.

iter_type do_get(iter_type in, iter_type end, ios_base& str, ios_base::iostate& err, bool& val) const;

Effects: Если (str.flags()&ios_­base​::​boolalpha) == 0 затем ввод происходит так же, как и для a, long за исключением того, что если значение сохраняетсяval, значение определяется в соответствии со следующим: Если значение, которое должно быть сохранено, равно 0, то false оно сохраняется. Если значение,1 то true сохраняется. В противном случаеtrue сохраняется иios_­base​::​failbit присваиваетсяerr.

В противном случае целевые последовательности определяются «как если бы» путем вызова членов falsename() и truename() фасета, полученного с помощью use_­facet<numpunct<charT>>(str.getloc()). Последовательные символы в диапазоне [in, end) (см.[sequence.reqmts]) Получаются и сопоставляются с соответствующими позициями в целевых последовательностях только по мере необходимости для идентификации уникального совпадения. Итератор вводаin сравниваетсяend только тогда, когда это необходимо для получения символа. Если целевая последовательность однозначно соответствует,val устанавливается соответствующее значение. В противном случаеfalse сохраняется иios_­base​::​failbit присваиваетсяerr.

in Итератор всегда остается указывая на одну позицию за пределы последнего символа, соответствующего образцу . Еслиval установлено, тоerr устанавливается в str.goodbit; или str.eofbit если при поиске другого символа для сопоставления обнаруживается, что (in == end). Еслиval не установлен, тоerr устанавливается в str.failbit; или (str.failbit|str.eofbit) если причина отказа была в этом (in == end). [ Example: Для целей true: "a" и false: "abb"входная последовательность "a" дает val == true и err == str.eofbit; входная последовательность "abc" дает результат err = str.failbitсin окончанием на 'c' элементе. Для целей true: "1" и false: "0"входная последовательность"1" дает val == true и err == str.goodbit. Для пустых целей("")любая входная последовательность дает результат err == str.failbit. ]end example

Returns: in.