Namespaces
Variants

std::num_get<CharT,InputIt>:: get, std::num_get<CharT,InputIt>:: do_get

From cppreference.net
std::num_get
Member functions
num_get::get num_get::do_get
**Примечание:** В данном фрагменте кода не требуется перевод, так как: - Весь текст находится внутри HTML-тегов форматирования кода - Содержит только C++ специфичные термины и синтаксис - Не содержит переводимого текстового контента HTML-разметка, атрибуты и C++ код сохранены в оригинальном виде в соответствии с требованиями. **Примечание:** В данном фрагменте кода не требуется перевод, так как: 1. Весь текст находится внутри тегов ` `, которые содержат C++ код 2. Согласно инструкциям, не переводится текст внутри тегов ` `, `
`, ``
3. Сохранены все HTML-теги и атрибуты без изменений
4. C++ специфические термины (virtual, iter_type, std::ios_base и т.д.) не переводятся
Форматирование и структура HTML полностью сохранены в оригинальном виде.
**Примечание:** В данном фрагменте кода не требуется перевод, так как: - Весь текст находится внутри HTML-тегов форматирования кода - Содержит исключительно C++ специфичные термины и синтаксис - Не содержит переводимого пользовательского текста HTML-разметка, атрибуты и C++ код сохранены в оригинальном виде в соответствии с требованиями. **Примечание:** Весь представленный код является C++ кодом и содержит только технические термины, которые не подлежат переводу согласно вашим требованиям. HTML теги, атрибуты и содержимое внутри тегов ` ` сохранены в оригинальном виде.
(1)
public :

iter_type get ( iter_type in, iter_type end, std:: ios_base & str,

std:: ios_base :: iostate & err, bool & v ) const ;
iter_type get ( iter_type in, iter_type end, std:: ios_base & str,
std:: ios_base :: iostate & err, long & v ) const ;
iter_type get ( iter_type in, iter_type end, std:: ios_base & str,
std:: ios_base :: iostate & err, long long & v ) const ;
(начиная с C++11)
iter_type get ( iter_type in, iter_type end, std:: ios_base & str,
std:: ios_base :: iostate & err, unsigned short & v ) const ;
iter_type get ( iter_type in, iter_type end, std:: ios_base & str,
std:: ios_base :: iostate & err, unsigned int & v ) const ;
iter_type get ( iter_type in, iter_type end, std:: ios_base & str,
std:: ios_base :: iostate & err, unsigned long & v ) const ;
iter_type get ( iter_type in, iter_type end, std:: ios_base & str,
std:: ios_base :: iostate & err, unsigned long long & v ) const ;
(начиная с C++11)
iter_type get ( iter_type in, iter_type end, std:: ios_base & str,
std:: ios_base :: iostate & err, float & v ) const ;
iter_type get ( iter_type in, iter_type end, std:: ios_base & str,
std:: ios_base :: iostate & err, double & v ) const ;
iter_type get ( iter_type in, iter_type end, std:: ios_base & str,
std:: ios_base :: iostate & err, long double & v ) const ;
iter_type get ( iter_type in, iter_type end, std:: ios_base & str,
std:: ios_base :: iostate & err, void * & v ) const ;
(2)
protected :

virtual iter_type do_get ( iter_type in, iter_type end, std:: ios_base & str,

std:: ios_base :: iostate & err, bool & v ) const ;
virtual iter_type do_get ( iter_type in, iter_type end, std:: ios_base & str,
std:: ios_base :: iostate & err, long & v ) const ;
virtual iter_type do_get ( iter_type in, iter_type end, std:: ios_base & str,
std:: ios_base :: iostate & err, long long & v ) const ;
(начиная с C++11)
virtual iter_type do_get ( iter_type in, iter_type end, std:: ios_base & str,
std:: ios_base :: iostate & err, unsigned short & v ) const ;
virtual iter_type do_get ( iter_type in, iter_type end, std:: ios_base & str,
std:: ios_base :: iostate & err, unsigned int & v ) const ;
virtual iter_type do_get ( iter_type in, iter_type end, std:: ios_base & str,
std:: ios_base :: iostate & err, unsigned long & v ) const ;
virtual iter_type do_get ( iter_type in, iter_type end, std:: ios_base & str,

std:: ios_base :: iostate & err,

unsigned long long & v ) const ;
(начиная с C++11)
virtual iter_type do_get ( iter_type in, iter_type end, std:: ios_base & str,
std:: ios_base :: iostate & err, float & v ) const ;
virtual iter_type do_get ( iter_type in, iter_type end, std:: ios_base & str,
std:: ios_base :: iostate & err, double & v ) const ;
virtual iter_type do_get ( iter_type in, iter_type end, std:: ios_base & str,
std:: ios_base :: iostate & err, long double & v ) const ;
virtual iter_type do_get ( iter_type in, iter_type end, std:: ios_base & str,
std:: ios_base :: iostate & err, void * & v ) const ;
1) Открытая функция-член, вызывает функцию-член do_get наиболее производного класса.
2) Считывает символы из входного итератора in и генерирует значение типа v , учитывая флаги форматирования потоков ввода-вывода из str. flags ( ) , правила классификации символов из std:: use_facet < std:: ctype < CharT >> ( str. getloc ( ) ) , и символы числовой пунктуации из std:: use_facet < std:: numpunct < CharT >> ( str. getloc ( ) ) . Эта функция вызывается всеми операторами форматированного ввода потоков, такими как std:: cin >> n ; .

Преобразование происходит в три этапа:

Содержание

Этап 1: выбор спецификатора преобразования

  • Флаги формата ввода-вывода получаются, как если бы
fmtflags basefield = ( str. flags ( ) & std:: ios_base :: basefield ) ;
fmtflags boolalpha = ( str. flags ( ) & std:: ios_base :: boolalpha ) ;
  • Если тип v является целочисленным, выбирается первый применимый вариант из следующих пяти:
Если basefield == oct , будет использоваться спецификатор преобразования % o
Если basefield == hex , будет использоваться спецификатор преобразования % X
Если basefield == 0 , будет использоваться спецификатор преобразования % i
Если тип v является знаковым, будет использоваться спецификатор преобразования % d
Если тип v является беззнаковым, будет использоваться спецификатор преобразования % u
  • Для целочисленных типов модификатор длины добавляется к спецификатору преобразования при необходимости: h для short и unsigned short , l для long и unsigned long , ll для long long и unsigned long long (начиная с C++11)
  • Если тип v float , будет использоваться спецификатор преобразования % g
  • Если тип v double , будет использоваться спецификатор преобразования % lg
  • Если тип v long double , будет использоваться спецификатор преобразования % Lg
  • Если тип v void * , будет использоваться спецификатор преобразования % p
  • Если тип v bool и boolalpha == 0 , выполняется так, как если бы тип v был long , за исключением значения, которое будет сохранено в v на этапе 3.
  • Если тип v bool и boolalpha ! = 0 , следующие этапы заменяют этапы 2 и 3:
    • Последовательные символы, полученные из входного итератора in , сопоставляются с последовательностями символов, полученными из std:: use_facet < std:: numpunct < CharT >> ( str. getloc ( ) ) . falsename ( ) и std:: use_facet < std:: numpunct < CharT >> ( str. getloc ( ) ) . truename ( ) только в той мере, в какой это необходимо для идентификации уникального совпадения. Входной итератор in сравнивается с end только при необходимости получения символа.
    • Если целевая последовательность однозначно совпадает, v устанавливается в соответствующее значение bool . В противном случае в v сохраняется false , и в err устанавливается std::ios_base::failbit . Если уникальное совпадение не было найдено до окончания ввода ( in == end ), выполняется err | = std:: ios_base :: eofbit .

Этап 2: извлечение символов

  • Если in == end , этап 2 немедленно завершается, дальнейшие символы не извлекаются.
  • Следующий символ извлекается из in как если бы с помощью char_type ct = * in ; :
    • Если символ совпадает с одним из "0123456789abcdefxABCDEFX+-" (до C++11) "0123456789abcdefpxABCDEFPX+-" (начиная с C++11) , расширенным до char_type локали как если бы с помощью std:: use_facet < std:: ctype < CharT >> ( str. getloc ( ) ) . widen ( ) , он преобразуется в соответствующий char .
    • Если символ совпадает с разделителем десятичной точки ( std:: use_facet < std:: numpunct < CharT >> ( str. getloc ( ) ) . decimal_point ( ) ) ), он заменяется на '.' .
    • Если символ совпадает с разделителем тысяч ( std:: use_facet < std:: numpunct < CharT >> ( str. getloc ( ) ) . thousands_sep ( ) ) и используется разделение тысяч (как определено с помощью std:: use_facet < std:: numpunct < CharT >> ( str. getloc ( ) ) . grouping ( ) . length ( ) ! = 0 ), тогда если десятичная точка '.' еще не была накоплена, позиция символа запоминается, но символ в остальном игнорируется. Если десятичная точка уже была накоплена, символ отбрасывается и этап 2 завершается.
    • В любом случае проверяется, разрешен ли char , полученный на предыдущих шагах, во входном поле, которое будет разбираться с помощью std::scanf с учетом спецификатора преобразования, выбранного на этапе 1. Если разрешен, он накапливается во временном буфере и этап 2 повторяется. Если не разрешен, этап 2 завершается.

Этап 3: преобразование и хранение

  • Последовательность char s, накопленная на этапе 2, преобразуется в числовое значение:
Ввод разбирается в соответствии с правилами std::scanf .
(до C++11)
Ввод разбирается как если бы с помощью
(начиная с C++11)
  • Если функция преобразования не может преобразовать всё поле, значение 0 сохраняется в v .
  • Если тип v является знаковым целочисленным типом и функция преобразования возвращает положительное или отрицательное значение, слишком большое для этого типа, в v сохраняется максимально возможное положительное или отрицательное представимое значение соответственно.
  • Если тип v является беззнаковым целочисленным типом и функция преобразования возвращает значение, которое не помещается в него, в v сохраняется максимально возможное положительное представимое значение.
  • В любом случае, если функция преобразования завершается неудачно, std::ios_base::failbit присваивается err .
  • В противном случае числовой результат преобразования сохраняется в v .
    • Если тип v bool и boolalpha не установлен, то если сохраняемое значение равно 0 , сохраняется false , если сохраняемое значение равно 1 , сохраняется true , для любого другого значения std::ios_base::failbit присваивается err и сохраняется true .
  • После этого проверяется группировка цифр. Если позиция любого из разделителей тысяч, отброшенных на этапе 2, не соответствует группировке, предоставляемой std:: use_facet < std:: numpunct < CharT >> ( str. getloc ( ) ) . grouping ( ) , std::ios_base::failbit присваивается err .
  • Если этап 2 был завершён проверкой in == end , выполняется err | = std:: ios_base :: eofbit для установки бита eof.

Возвращаемое значение

in

Примечания

До разрешения LWG issue 23 и LWG issue 696 , v оставался неизменным в случае возникновения ошибки.

До разрешения LWG issue 221 , строки, представляющие шестнадцатеричные целые числа (например, "0xA0" ), отклонялись функцией do_get(int) даже если они являются допустимым вводом для strtol , поскольку этап 2 отфильтровывает символы 'X' и 'x' .

До разрешения LWG issue 1169 , преобразование строки с отрицательным числом в беззнаковое целое могло приводить к нулю (поскольку значение, представленное строкой, меньше того, которое может представить целевой тип).

До решения проблемы LWG 2381 строки, представляющие шестнадцатеричные числа с плавающей точкой с экспонентами (например, "0x1.23p-10" ), отклонялись методом do_get(double) даже если они являются допустимым вводом для strtod , поскольку этап 2 отфильтровывает символы 'P' и 'p' .

Строки, представляющие бесконечность или не-число (например, "NaN" и "inf" ), отклоняются методом do_get(double) даже если они являются допустимым вводом для strtod , поскольку этап 2 отфильтровывает символы такие как 'N' или 'i' .

(начиная с C++11)

Пример

Реализация оператора operator>> для пользовательского типа.

#include <iostream>
#include <iterator>
#include <locale>
struct base { long x; };
template<class CharT, class Traits>
std::basic_istream<CharT, Traits>&
    operator >>(std::basic_istream<CharT, Traits>& is, base& b)
{
    std::ios_base::iostate err = std::ios_base::goodbit;
    try // setting err could throw
    {
        typename std::basic_istream<CharT, Traits>::sentry s(is);
        if (s) // if stream is ready for input
            std::use_facet<std::num_get<CharT>>(is.getloc()).get(is, {}, is, err, b.x);
    }
    catch (std::ios_base::failure& error)
    {
        // handle the exception
    }
    return is;
}
int main()
{
    base b;
    std::cin >> b;
}

Отчеты о дефектах

Следующие отчеты об изменениях в поведении, содержащие описания дефектов, были применены ретроактивно к ранее опубликованным стандартам C++.

DR Применено к Поведение в опубликованной версии Исправленное поведение
LWG 17 C++98 процесс разбора текстовых булевых значений содержал ошибки исправлено
LWG 18 C++98 перегрузка get принимающая bool & значение отсутствовала добавлена
LWG 23 C++98 переполнение ввода приводило к неопределенному поведению переполнение обрабатывается
LWG 154 C++98 спецификатор преобразования для double был % g (такой же как для float ) изменен на % lg
LWG 221 C++98 do_get не разбирал 'x' и 'X' тогда как strtol разбирал их сделано так, чтобы 'x' и 'X' разбирались
LWG 275 C++98 get имел перегрузку принимающую short & вместо float & исправлено
LWG 358 C++98 разделители тысяч после десятичной точки игнорировались этап 2 завершается при их обнаружении
LWG 696 C++98 результат не изменялся при неудачном преобразовании устанавливается в ноль
LWG 1169 C++98 обработка переполнения была несогласованной между типами с плавающей точкой сделана согласованной
с strtof / strtod
LWG 2381 C++11 do_get не разбирал 'p' и 'P' тогда как strtod разбирал их сделано так, чтобы 'p' и 'P' разбирались

Смотрите также

извлекает форматированные данные
(публичная функция-член std::basic_istream<CharT,Traits> )