В этом разделе описаны компоненты, которые программы на C ++ могут использовать для инкапсуляции (и, следовательно, большей переносимости при столкновении с культурными различиями). Средство локали включает поддержку интернационализации для классификации символов и сопоставления строк, числового, денежного форматирования и форматирования и анализа даты / времени, а также извлечения сообщений.
В следующих подпунктах описываются компоненты для самих локалей, стандартные аспекты и возможности библиотеки ISO C, как показано в таблице 68.
Подпункт | Заголовок (ы) | |
[locales] | Locales | <locale> |
[locale.categories] | Стандартные locale категории | |
[c.locales] | Языковые стандарты библиотеки C | <clocale> |
namespace std { // [locale], locale class locale; template <class Facet> const Facet& use_facet(const locale&); template <class Facet> bool has_facet(const locale&) noexcept; // [locale.convenience], convenience interfaces template <class charT> bool isspace (charT c, const locale& loc); template <class charT> bool isprint (charT c, const locale& loc); template <class charT> bool iscntrl (charT c, const locale& loc); template <class charT> bool isupper (charT c, const locale& loc); template <class charT> bool islower (charT c, const locale& loc); template <class charT> bool isalpha (charT c, const locale& loc); template <class charT> bool isdigit (charT c, const locale& loc); template <class charT> bool ispunct (charT c, const locale& loc); template <class charT> bool isxdigit(charT c, const locale& loc); template <class charT> bool isalnum (charT c, const locale& loc); template <class charT> bool isgraph (charT c, const locale& loc); template <class charT> bool isblank (charT c, const locale& loc); template <class charT> charT toupper(charT c, const locale& loc); template <class charT> charT tolower(charT c, const locale& loc); // [category.ctype], ctype class ctype_base; template <class charT> class ctype; template <> class ctype<char>; // specialization template <class charT> class ctype_byname; class codecvt_base; template <class internT, class externT, class stateT> class codecvt; template <class internT, class externT, class stateT> class codecvt_byname; // [category.numeric], numeric template <class charT, class InputIterator = istreambuf_iterator<charT>> class num_get; template <class charT, class OutputIterator = ostreambuf_iterator<charT>> class num_put; template <class charT> class numpunct; template <class charT> class numpunct_byname; // [category.collate], collation template <class charT> class collate; template <class charT> class collate_byname; // [category.time], date and time class time_base; template <class charT, class InputIterator = istreambuf_iterator<charT>> class time_get; template <class charT, class InputIterator = istreambuf_iterator<charT>> class time_get_byname; template <class charT, class OutputIterator = ostreambuf_iterator<charT>> class time_put; template <class charT, class OutputIterator = ostreambuf_iterator<charT>> class time_put_byname; // [category.monetary], money class money_base; template <class charT, class InputIterator = istreambuf_iterator<charT>> class money_get; template <class charT, class OutputIterator = ostreambuf_iterator<charT>> class money_put; template <class charT, bool Intl = false> class moneypunct; template <class charT, bool Intl = false> class moneypunct_byname; // [category.messages], message retrieval class messages_base; template <class charT> class messages; template <class charT> class messages_byname; }
Заголовок <locale> определяет классы и объявляет функции, которые инкапсулируют и обрабатывают информацию, специфичную для локали.229
namespace std { class locale { public: // types: class facet; class id; using category = int; static const category // values assigned here are for exposition only none = 0, collate = 0x010, ctype = 0x020, monetary = 0x040, numeric = 0x080, time = 0x100, messages = 0x200, all = collate | ctype | monetary | numeric | time | messages; // construct/copy/destroy: locale() noexcept; locale(const locale& other) noexcept; explicit locale(const char* std_name); explicit locale(const string& std_name); locale(const locale& other, const char* std_name, category); locale(const locale& other, const string& std_name, category); template <class Facet> locale(const locale& other, Facet* f); locale(const locale& other, const locale& one, category); ~locale(); // not virtual const locale& operator=(const locale& other) noexcept; template <class Facet> locale combine(const locale& other) const; // locale operations: basic_string<char> name() const; bool operator==(const locale& other) const; bool operator!=(const locale& other) const; template <class charT, class traits, class Allocator> bool operator()(const basic_string<charT, traits, Allocator>& s1, const basic_string<charT, traits, Allocator>& s2) const; // global locale objects: static locale global(const locale&); static const locale& classic(); }; }
Класс locale реализует безопасный для типов полиморфный набор фасетов, индексированных фасетами type. Другими словами, фасет выполняет двойную роль: в каком-то смысле это просто интерфейс класса; в то же время, это указатель на набор аспектов локали.
[ Example: Iostream operator<< может быть реализован как:230
template <class charT, class traits>
basic_ostream<charT, traits>&
operator<< (basic_ostream<charT, traits>& s, Date d) {
typename basic_ostream<charT, traits>::sentry cerberos(s);
if (cerberos) {
ios_base::iostate err = ios_base::iostate::goodbit;
tm tmbuf; d.extract(tmbuf);
use_facet<time_put<charT, ostreambuf_iterator<charT, traits>> >(
s.getloc()).put(s, s, s.fill(), err, &tmbuf, 'x');
s.setstate(err); // might throw
}
return s;
}
— end example ]
При вызове use_facet<Facet>(loc)аргумент типа выбирает фасет, делая доступными все члены именованного типа. Если Facet его нет в локали, генерируется стандартное исключение bad_cast. Программа на C ++ может проверить, реализует ли локаль определенный аспект с шаблоном функции has_facet<Facet>(). Определяемые пользователем фасеты могут быть установлены в локали и использоваться так же, как и стандартные фасеты ([facets.examples]).
[ Note: Доступ ко всей семантике языкового стандарта осуществляется через use_facet<> и has_facet<>, за исключением следующих:
Предоставляется шаблон оператора-члена, operator()(const basic_string<C, T, A>&, const basic_string<C, T, A>&) чтобы языковой стандарт можно было использовать в качестве аргумента предиката для стандартных коллекций для сопоставления строк.
Для традиционныхctype функций, таких как isdigit() и isspace(), предоставляются удобные глобальные интерфейсы , поэтому loc программа на C ++ может вызывать объект языкового стандартаisspace(c, loc). (Это упрощает обновление существующих экстракторов ([istream.formatted]).)
— end note ]
После получения ссылки на фасет из объекта языкового стандарта путем вызова use_facet<>эта ссылка остается пригодной для использования, а результаты его функций-членов могут кэшироваться и повторно использоваться, если какой-либо объект языкового стандарта ссылается на этот фасет.
При последовательных вызовах функции-члена фасета локали для объекта фасета, установленного в той же локали, возвращаемый результат должен быть идентичным.
locale Построено из имени строки (например , как "POSIX"), или из частей двух названных районов, имеет имя; все остальные этого не делают. Именованные языковые стандарты можно сравнивать на предмет равенства; безымянный языковой стандарт равен только (копиям) самого себя. Для безымянного языкового стандарта locale::name() возвращает строку "*".
Независимо от того, существует ли один глобальный объект языкового стандарта для всей программы или один глобальный объект языкового стандарта для каждого потока, определяется реализацией. Реализации должны предоставлять один глобальный объект локали для каждого потока. Если для всей программы существует один глобальный объект локали, реализация на нем не требуется avoid data races .
Обратите внимание, что при вызове put потока неявно преобразуется в ostreambuf_iterator<charT, traits>.
using category = int;
Valid category значения включают в себяlocale член битовая маска элементы collate, ctype, monetary, numeric, time, и messages, каждый из которых представляет одну категорию локали. Кроме того, locale константа битовой маски элемента none определяется как ноль и не представляет категории. И locale постоянный член битовой маски all определяются таким образом, что выражение
(collate | ctype | monetary | numeric | time | messages | all) == all
есть true, и представляет собой объединение всех категорий. Кроме того, выражение (X | Y), где X и Y каждое представляет одну категорию, представляет собой объединение двух категорий.
locale Функции-члены, ожидающие category аргумента, требуют одного из category значений, определенных выше, или объединения двух или более таких значений. Такое category значение определяет набор категорий локали. Каждая категория языкового стандарта, в свою очередь, определяет набор аспектов языкового стандарта, включая, по крайней мере, те, которые показаны в таблице 69.
Категория | Включает грани |
сопоставлять | collate<char>, collate<wchar_t> |
ctype | ctype<char>, ctype<wchar_t> |
codecvt<char, char, mbstate_t> | |
codecvt<char16_t, char, mbstate_t> | |
codecvt<char32_t, char, mbstate_t> | |
codecvt<wchar_t, char, mbstate_t> | |
денежный | moneypunct<char>, moneypunct<wchar_t> |
moneypunct<char, true>, moneypunct<wchar_t, true> | |
money_get<char>, money_get<wchar_t> | |
money_put<char>, money_put<wchar_t> | |
числовой | numpunct<char>, numpunct<wchar_t> |
num_get<char>, num_get<wchar_t> | |
num_put<char>, num_put<wchar_t> | |
время | time_get<char>, time_get<wchar_t> |
time_put<char>, time_put<wchar_t> | |
Сообщения | messages<char>, messages<wchar_t> |
Для любой локали loc , созданной или возвращенной locale::classic(), и любого аспекта, Facet показанного в таблице 69, has_facet<Facet>(loc) есть true. Каждая locale функция-член, которая принимает locale::category аргумент, работает с соответствующим набором аспектов.
Реализация требуется для предоставления этих специализаций для шаблонов аспектов, определенных как члены категории, и для тех, которые показаны в таблице 70.
Категория | Включает грани |
сопоставлять | collate_byname<char>, collate_byname<wchar_t> |
ctype | ctype_byname<char>, ctype_byname<wchar_t> |
codecvt_byname<char, char, mbstate_t> | |
codecvt_byname<char16_t, char, mbstate_t> | |
codecvt_byname<char32_t, char, mbstate_t> | |
codecvt_byname<wchar_t, char, mbstate_t> | |
денежный | moneypunct_byname<char, International> |
moneypunct_byname<wchar_t, International> | |
money_get<C, InputIterator> | |
money_put<C, OutputIterator> | |
числовой | numpunct_byname<char>, numpunct_byname<wchar_t> |
num_get<C, InputIterator>, num_put<C, OutputIterator> | |
время | time_get<char, InputIterator> |
time_get_byname<char, InputIterator> | |
time_get<wchar_t, InputIterator> | |
time_get_byname<wchar_t, InputIterator> | |
time_put<char, OutputIterator> | |
time_put_byname<char, OutputIterator> | |
time_put<wchar_t, OutputIterator> | |
time_put_byname<wchar_t, OutputIterator> | |
Сообщения | messages_byname<char>, messages_byname<wchar_t> |
Предоставленная реализация членов фасетов num_get<charT> и num_put<charT> вызовов use_facet<F>(l) только для фасетов F типов numpunct<charT> и ctype<charT>, а для локали l значение, полученное путем вызова member getloc() для ios_base& аргумента этих функций.
В объявлениях фасетов параметр шаблона с именем InputIterator или OutputIterator указывает набор всех возможных специализаций параметров, которые удовлетворяют требованиям итератора ввода или итератора вывода, соответственно ([iterator.requirements]). Параметр шаблона с именем C представляет собой набор типов , содержащих char, wchar_tи любых других реализации определенных типов символов , которые удовлетворяют требования , предъявляемые к характеру , на которых любые из компонентов iostream может быть реализованным. Параметр шаблона с именем International представляет собой набор всех возможных специализаций для параметра типа bool.
namespace std { class locale::facet { protected: explicit facet(size_t refs = 0); virtual ~facet(); facet(const facet&) = delete; void operator=(const facet&) = delete; }; }
Класс facet - это базовый класс для наборов функций локали. Класс - это класс, facet если он является производным от другого аспекта или если он является производным от класса locale::facet и содержит следующее публично доступное объявление:231
static ::std::locale::id id;
Параметры шаблона в этом разделе, которые должны быть фасетами, являются теми, которые указаны Facet в объявлениях. Программа, которая передает тип, который является not фасетом, или тип, который ссылается на фасет с изменяемым атрибутом в качестве (явного или выведенного) параметра шаблона в функцию языкового стандарта, ожидающую фасета, имеет неправильный формат. Фасет с константой является допустимым аргументом шаблона для любой функции локали, которая ожидает параметр шаблона Facet.
refs Аргумент конструктора используется для управления жизненным циклом. Для refs == 0реализации выполняется delete static_cast<locale::facet*>(f) (где f - указатель на фасет), когда последний locale объект, содержащий фасет, уничтожается; ведь refs == 1реализация никогда не разрушает фасет.
Конструкторы всех фасетов, определенных в этом разделе, принимают такой аргумент и передают его конструктору своего facet базового класса. Все конструкторы с одним аргументом, определенные в этом разделе explicit, предотвращают их участие в автоматических преобразованиях.
Для некоторых стандартных аспектов…_bynameпроизводный от него стандартный класс « » реализует семантику виртуальных функций, эквивалентную этому аспекту локали, созданного locale(const char*) с помощью того же имени. Каждый такой аспект предоставляет конструктор, который принимает const char* аргумент, который называет локаль, и refs аргумент, который передается конструктору базового класса. Каждый такой аспект также предоставляет конструктор, который принимает string аргумент str и refs аргумент, который имеет тот же эффект, что и вызов первого конструктора с двумя аргументами str.c_str() и refs. Если нет «…_byname» версии фасета, базовый класс сам реализует именованную семантику локали, ссылаясь на другие фасеты.
Это полный список требований; других требований нет. Таким образом, класс фасета не обязательно должен иметь общедоступный конструктор копирования, присваивание, конструктор по умолчанию, деструктор и т. Д.
namespace std { class locale::id { public: id(); void operator=(const id&) = delete; id(const id&) = delete; }; }
Класс locale::id обеспечивает идентификацию интерфейса фасета локали, используемого в качестве индекса для поиска и инкапсуляции инициализации.
[ Note: Поскольку фасеты используются iostreams, потенциально во время работы статических конструкторов их инициализация не может зависеть от запрограммированной статической инициализации. Одна стратегия инициализации заключается locale в инициализации каждогоid члена фасета при первой установке экземпляра фасета в локаль. Это зависит только от нуля статического хранилища перед запуском конструктора ([basic.start.static]). ] — end note
locale() noexcept;
Effects: Создает копию последнего переданного аргумента locale::global(locale&), если он был вызван; иначе, результирующие фасеты имеют семантику виртуальных функций, идентичную семантике locale::classic(). [ Note: Этот конструктор обычно используется в качестве значения по умолчанию для аргументов функций, которые принимают const locale& аргумент. ] — end note
locale(const locale& other) noexcept;
explicit locale(const char* std_name);
Effects: Создает языковой стандарт с использованием стандартных имен языковых стандартов C, например "POSIX". Результирующий языковой стандарт реализует семантику, связанную с этим именем.
explicit locale(const string& std_name);
locale(const locale& other, const char* std_name, category);
Effects: Создает локаль как копию, за other исключением аспектов, определенных category аргументом, которые вместо этого реализуют ту же семантику, что и locale(std_name).
locale(const locale& other, const string& std_name, category cat);
template <class Facet> locale(const locale& other, Facet* f);
Effects: Создает локаль, включающую все фасеты из первого аргумента, кромеFacetфасета типа , и устанавливает второй аргумент как оставшийся фасет. Если f имеет значение null, результирующий объект является копией other.
locale(const locale& other, const locale& one, category cats);
Effects: Создает локаль, включающую все фасеты из первого аргумента, кроме тех, которые реализуют cats, которые вместо этого включены из второго аргумента.
Remarks: Результирующая локаль имеет имя тогда и только тогда, когда у первых двух аргументов есть имена.
const locale& operator=(const locale& other) noexcept;
~locale();
template <class Facet> locale combine(const locale& other) const;
Effects: Создает языковой стандарт, включающий все аспекты из, *this за исключением того одного аспекта, other который идентифицирован Facet.
basic_string<char> name() const;
bool operator==(const locale& other) const;
Returns: true если оба аргумента являются одним и тем же языковым стандартом, или один является копией другого, или каждый имеет имя и имена идентичны; false иначе.
bool operator!=(const locale& other) const;
template <class charT, class traits, class Allocator>
bool operator()(const basic_string<charT, traits, Allocator>& s1,
const basic_string<charT, traits, Allocator>& s2) const;
Remarks: Этот шаблон оператора-члена (и, следовательно, locale сам) удовлетворяет требованиям для аргумента (предложение [algorithms]) шаблона предиката компаратора, применяемого к строкам.
Returns:
use_facet<collate<charT>>(*this).compare(s1.data(), s1.data() + s1.size(), s2.data(), s2.data() + s2.size()) < 0
[ Example: Вектор строк v можно сопоставить в соответствии с правилами сопоставления в локали loc просто с помощью ([alg.sort], [vector]):
std::sort(v.begin(), v.end(), loc);
— end example ]
static locale global(const locale& loc);
Effects: Заставляет будущие вызовы конструктора locale() возвращать копию аргумента. Если аргумент имеет имя, не
setlocale(LC_ALL, loc.name().c_str());
в противном случае влияние на локаль C, если таковая имеется, определяется реализацией. Никакая другая библиотечная функция не locale::global() должна влиять на значение, возвращаемое locale(). [ Note: См. [c.locales] Соображенияsetlocale по поводу гонки данных при вызове. ] — end note
static const locale& classic();
Returns: Языковой стандарт, реализующий "C" семантику классического языкового стандарта, эквивалентный значению locale("C").
template <class Facet> const Facet& use_facet(const locale& loc);
Requires: Facet - это фасетный класс, определение которого содержит публичный статический член, id как определено в [locale.facet].
Remarks: Возвращенная ссылка остается действительной по крайней мере до тех пор, пока существует любая копия loc .
template <class Facet> bool has_facet(const locale& loc) noexcept;
template <class charT> bool isspace (charT c, const locale& loc);
template <class charT> bool isprint (charT c, const locale& loc);
template <class charT> bool iscntrl (charT c, const locale& loc);
template <class charT> bool isupper (charT c, const locale& loc);
template <class charT> bool islower (charT c, const locale& loc);
template <class charT> bool isalpha (charT c, const locale& loc);
template <class charT> bool isdigit (charT c, const locale& loc);
template <class charT> bool ispunct (charT c, const locale& loc);
template <class charT> bool isxdigit(charT c, const locale& loc);
template <class charT> bool isalnum (charT c, const locale& loc);
template <class charT> bool isgraph (charT c, const locale& loc);
template <class charT> bool isblank (charT c, const locale& loc);
Каждая из этих функций isF возвращает результат выражения:
use_facet<ctype<charT>>(loc).is(ctype_base::F, c)
где F - ctype_base::mask значение, соответствующее этой функции ([category.ctype]).232
При использовании в цикле быстрее кэшировать ctype<> фасет и использовать его напрямую или использовать векторную форму ctype<>::is.
template <class charT> charT toupper(charT c, const locale& loc);
template <class charT> charT tolower(charT c, const locale& loc);
Каждая из стандартных категорий включает в себя семейство аспектов. Некоторые из них реализуют форматирование или синтаксический анализ данных для использования стандартными или пользовательскими операторами iostream << и в >>качестве членов put() и get(), соответственно. Каждая такая функция члена принимает ios_base& аргумент, члены которого flags(), precision()и width(), указать формат соответствующего элемента данных ([ios.base]). Те функции, которым необходимо использовать другие фасеты, вызывают его член, getloc() чтобы получить заложенный там языковой стандарт. Фасеты форматирования используют символьный аргумент fill для заполнения указанной ширины там, где это необходимо.
В put() членах не предусмотрены для сообщений об ошибках. (Любые сбои аргумента OutputIterator должны быть извлечены из возвращенного итератора.) get() Члены принимают ios_base::iostate& аргумент, значение которого они игнорируют, но устанавливают ios_base::failbit в случае ошибки синтаксического анализа.
namespace std { class ctype_base { public: using mask = T; // numeric values are for exposition only. static const mask space = 1 << 0; static const mask print = 1 << 1; static const mask cntrl = 1 << 2; static const mask upper = 1 << 3; static const mask lower = 1 << 4; static const mask alpha = 1 << 5; static const mask digit = 1 << 6; static const mask punct = 1 << 7; static const mask xdigit = 1 << 8; static const mask blank = 1 << 9; static const mask alnum = alpha | digit; static const mask graph = alnum | punct; }; }
namespace std { template <class charT> class ctype : public locale::facet, public ctype_base { public: using char_type = charT; explicit ctype(size_t refs = 0); bool is(mask m, charT c) const; const charT* is(const charT* low, const charT* high, mask* vec) const; const charT* scan_is(mask m, const charT* low, const charT* high) const; const charT* scan_not(mask m, const charT* low, const charT* high) const; charT toupper(charT c) const; const charT* toupper(charT* low, const charT* high) const; charT tolower(charT c) const; const charT* tolower(charT* low, const charT* high) const; charT widen(char c) const; const char* widen(const char* low, const char* high, charT* to) const; char narrow(charT c, char dfault) const; const charT* narrow(const charT* low, const charT* high, char dfault, char* to) const; static locale::id id; protected: ~ctype(); virtual bool do_is(mask m, charT c) const; virtual const charT* do_is(const charT* low, const charT* high, mask* vec) const; virtual const charT* do_scan_is(mask m, const charT* low, const charT* high) const; virtual const charT* do_scan_not(mask m, const charT* low, const charT* high) const; virtual charT do_toupper(charT) const; virtual const charT* do_toupper(charT* low, const charT* high) const; virtual charT do_tolower(charT) const; virtual const charT* do_tolower(charT* low, const charT* high) const; virtual charT do_widen(char) const; virtual const char* do_widen(const char* low, const char* high, charT* dest) const; virtual char do_narrow(charT, char dfault) const; virtual const charT* do_narrow(const charT* low, const charT* high, char dfault, char* dest) const; }; }
Класс ctype инкапсулирует библиотеки C <cctype> функции. istream члены должны использоваться ctype<> для классификации символов во время синтаксического анализа входных данных.
Специализации, требуемые в Table 69 ([locale.category]), а именно ctype<char> и ctype<wchar_t>, реализуют классификацию символов, соответствующую собственному набору символов реализации.
bool is(mask m, charT c) const;
const charT* is(const charT* low, const charT* high,
mask* vec) const;
const charT* scan_is(mask m,
const charT* low, const charT* high) const;
const charT* scan_not(mask m,
const charT* low, const charT* high) const;
charT toupper(charT) const;
const charT* toupper(charT* low, const charT* high) const;
charT tolower(charT c) const;
const charT* tolower(charT* low, const charT* high) const;
charT widen(char c) const;
const char* widen(const char* low, const char* high, charT* to) const;
char narrow(charT c, char dfault) const;
const charT* narrow(const charT* low, const charT* high, char dfault,
char* to) const;
bool do_is(mask m, charT c) const;
const charT* do_is(const charT* low, const charT* high,
mask* vec) const;
Effects: Классифицирует символ или последовательность символов. Для каждого символа аргумента определяет значение M типа ctype_base::mask. Вторая форма определяет значение M типа ctype_base::mask для каждого *p where (low <= p && p < high)и помещает его в vec[p - low].
Returns: Первая форма возвращает результат выражения (M & m) != 0; то есть, true если персонаж имеет указанные характеристики. Вторая форма возвращается high.
const charT* do_scan_is(mask m, const charT* low, const charT* high) const;
Returns: Наименьший указатель p в диапазоне [low, high) , который is(m, *p) будет возвращать true; в противном случае возвращается high.
const charT* do_scan_not(mask m, const charT* low, const charT* high) const;
Returns: Наименьший указатель p, если таковой имеется, в диапазоне [low, high) , который is(m, *p) может возвращать false; в противном случае возвращается high.
charT do_toupper(charT c) const;
const charT* do_toupper(charT* low, const charT* high) const;
Effects: Преобразует символ или символы в верхний регистр. Вторая форма заменяет каждый символ *p в диапазоне, [low, high) для которого существует соответствующий символ верхнего регистра, этим символом.
Returns: Первая форма возвращает соответствующий символ верхнего регистра, если известно, что он существует, или его аргумент, если нет. Вторая форма возвращается high.
charT do_tolower(charT c) const;
const charT* do_tolower(charT* low, const charT* high) const;
Effects: Преобразует символ или символы в нижний регистр. Вторая форма заменяет каждый символ *p в диапазоне, [low, high) для которого существует соответствующий символ нижнего регистра, на этот символ.
Returns: Первая форма возвращает соответствующий символ нижнего регистра, если известно, что он существует, или его аргумент, если нет. Вторая форма возвращается high.
charT do_widen(char c) const;
const char* do_widen(const char* low, const char* high,
charT* dest) const;
Effects: Применяет простейшее разумное преобразование char значения или последовательности char значений в соответствующее charT значение или значения.233 Единственные символы, для которых требуются уникальные преобразования, - это символы в basic source character set.
Для любого имени ctype категории с ctype <charT> фаской ctc и действительным ctype_base::mask значением M, (ctc.is(M, c) || !is(M, do_widen(c)) ) является true.234
Вторая форма преобразует каждый символ *p в диапазоне [low, high), помещая результат в dest[p - low].
char do_narrow(charT c, char dfault) const;
const charT* do_narrow(const charT* low, const charT* high,
char dfault, char* dest) const;
Effects: Применяет простейшее разумное преобразование charT значения или последовательности charT значений в соответствующее char значение или значения.
Для любого символа c в basic source character set преобразовании таково, что
do_widen(do_narrow(c, 0)) == c
Для любого имени ctype категории с ctype<char> фаской ctc однако, и ctype_base::mask значением M,
(is(M, c) || !ctc.is(M, do_narrow(c, dfault)) )
есть true (если не do_narrow возвращается dfault). Кроме того, для любого цифрового символа cвыражение (do_narrow(c, dfault) - '0') оценивается как цифровое значение символа. Вторая форма преобразует каждый символ *p в диапазоне [low, high), помещая результат (или, dfault если простое преобразование недоступно) в dest[p - low].
Returns: Первая форма возвращает преобразованное значение; или dfault если нет доступного отображения. Вторая форма возвращается high.
Аргумент char do_widen предназначен для приема значений, полученных из символьных литералов, для преобразования в кодировку языкового стандарта.
Другими словами, преобразованный символ не является членом какой-либо классификации символов, которая c также не является членом.
namespace std { template <class charT> class ctype_byname : public ctype<charT> { public: using mask = typename ctype<charT>::mask; explicit ctype_byname(const char*, size_t refs = 0); explicit ctype_byname(const string&, size_t refs = 0); protected: ~ctype_byname(); }; }
namespace std {
template <>
class ctype<char> : public locale::facet, public ctype_base {
public:
using char_type = char;
explicit ctype(const mask* tab = 0, bool del = false,
size_t refs = 0);
bool is(mask m, char c) const;
const char* is(const char* low, const char* high, mask* vec) const;
const char* scan_is (mask m,
const char* low, const char* high) const;
const char* scan_not(mask m,
const char* low, const char* high) const;
char toupper(char c) const;
const char* toupper(char* low, const char* high) const;
char tolower(char c) const;
const char* tolower(char* low, const char* high) const;
char widen(char c) const;
const char* widen(const char* low, const char* high, char* to) const;
char narrow(char c, char dfault) const;
const char* narrow(const char* low, const char* high, char dfault,
char* to) const;
static locale::id id;
static const size_t table_size = implementation-defined;
const mask* table() const noexcept;
static const mask* classic_table() noexcept;
protected:
~ctype();
virtual char do_toupper(char c) const;
virtual const char* do_toupper(char* low, const char* high) const;
virtual char do_tolower(char c) const;
virtual const char* do_tolower(char* low, const char* high) const;
virtual char do_widen(char c) const;
virtual const char* do_widen(const char* low,
const char* high,
char* to) const;
virtual char do_narrow(char c, char dfault) const;
virtual const char* do_narrow(const char* low,
const char* high,
char dfault, char* to) const;
};
}
Предоставляется специализация, позволяющая реализовать ctype<char> функции-члены по типу . Определяемое реализацией значение member не менее 256.charinline235table_size
Только char (не unsigned char и signed char) форма предоставляется. Специализация указывается в стандарте и не остается в качестве детали реализации, поскольку она влияет на интерфейс деривации для ctype<char>.
~ctype();
В следующих описаниях членов для unsigned char значений, v где предполагается, что они имеют значение v >= table_size, table()[v] зависящее от реализации (возможно, различное для каждого такого значения v), без выполнения поиска в массиве.
explicit ctype(const mask* tbl = 0, bool del = false,
size_t refs = 0);
bool is(mask m, char c) const;
const char* is(const char* low, const char* high,
mask* vec) const;
Effects: Вторая форма для всех *p в диапазоне [low, high)присваивается vec[p - low] значению table()[(unsigned char)*p].
const char* scan_is(mask m,
const char* low, const char* high) const;
const char* scan_not(mask m,
const char* low, const char* high) const;
Returns: Наименьшее p в диапазоне [low, high) такое, что
table()[(unsigned char) *p] & m
есть false.
char toupper(char c) const;
const char* toupper(char* low, const char* high) const;
char tolower(char c) const;
const char* tolower(char* low, const char* high) const;
char widen(char c) const;
const char* widen(const char* low, const char* high,
char* to) const;
char narrow(char c, char dfault) const;
const char* narrow(const char* low, const char* high,
char dfault, char* to) const;
const mask* table() const noexcept;
static const mask* classic_table() noexcept;
char do_toupper(char) const; const char* do_toupper(char* low, const char* high) const; char do_tolower(char) const; const char* do_tolower(char* low, const char* high) const; virtual char do_widen(char c) const; virtual const char* do_widen(const char* low, const char* high, char* to) const; virtual char do_narrow(char c, char dfault) const; virtual const char* do_narrow(const char* low, const char* high, char dfault, char* to) const;
Эти функции описаны так же, как и члены с тем же именем в ctype class template.
namespace std { class codecvt_base { public: enum result { ok, partial, error, noconv }; }; template <class internT, class externT, class stateT> class codecvt : public locale::facet, public codecvt_base { public: using intern_type = internT; using extern_type = externT; using state_type = stateT; explicit codecvt(size_t refs = 0); result out( stateT& state, const internT* from, const internT* from_end, const internT*& from_next, externT* to, externT* to_end, externT*& to_next) const; result unshift( stateT& state, externT* to, externT* to_end, externT*& to_next) const; result in( stateT& state, const externT* from, const externT* from_end, const externT*& from_next, internT* to, internT* to_end, internT*& to_next) const; int encoding() const noexcept; bool always_noconv() const noexcept; int length(stateT&, const externT* from, const externT* end, size_t max) const; int max_length() const noexcept; static locale::id id; protected: ~codecvt(); virtual result do_out( stateT& state, const internT* from, const internT* from_end, const internT*& from_next, externT* to, externT* to_end, externT*& to_next) const; virtual result do_in( stateT& state, const externT* from, const externT* from_end, const externT*& from_next, internT* to, internT* to_end, internT*& to_next) const; virtual result do_unshift( stateT& state, externT* to, externT* to_end, externT*& to_next) const; virtual int do_encoding() const noexcept; virtual bool do_always_noconv() const noexcept; virtual int do_length(stateT&, const externT* from, const externT* end, size_t max) const; virtual int do_max_length() const noexcept; }; }
Класс codecvt<internT, externT, stateT> предназначен для использования при преобразовании из одной кодировки символов в другую, например, из широких символов в многобайтовые символы или между кодировками широких символов, такими как Unicode и EUC.
Специализации, требуемые в Table 69 ([locale.category]), преобразуют собственный набор символов, определенный реализацией. codecvt<char, char, mbstate_t> реализует вырожденное преобразование; он вообще не конвертируется. Специализация codecvt<char16_t, char, mbstate_t> преобразуется между формами кодирования UTF-16 и UTF-8, а специализация codecvt <char32_t, char, mbstate_t> преобразуется между формами кодирования UTF-32 и UTF-8. codecvt<wchar_t, char, mbstate_t> преобразует собственные наборы символов для узких и широких символов. Специализации по mbstate_t выполнению преобразования между кодировками, известные разработчику библиотеки. Другие кодировки можно преобразовать, специализируясь на определяемом пользователем stateT типе. Объекты типа stateT могут содержать любое состояние, которое полезно для связи со специализированнымиdo_in или do_out членами или от них .
result out(
stateT& state,
const internT* from, const internT* from_end, const internT*& from_next,
externT* to, externT* to_end, externT*& to_next) const;
result unshift(stateT& state, externT* to, externT* to_end, externT*& to_next) const;
result in(
stateT& state,
const externT* from, const externT* from_end, const externT*& from_next,
internT* to, internT* to_end, internT*& to_next) const;
int encoding() const noexcept;
bool always_noconv() const noexcept;
int length(stateT& state, const externT* from, const externT* from_end, size_t max) const;
int max_length() const noexcept;
result do_out(
stateT& state,
const internT* from, const internT* from_end, const internT*& from_next,
externT* to, externT* to_end, externT*& to_next) const;
result do_in(
stateT& state,
const externT* from, const externT* from_end, const externT*& from_next,
internT* to, internT* to_end, internT*& to_next) const;
Requires: (from <= from_end && to <= to_end) четко определенные и true; state инициализируется, если оно находится в начале последовательности, или равно результату преобразования предыдущих символов в последовательности.
Effects: Переводит символы в исходном диапазоне [from, from_end), помещая результаты в последовательные позиции, начиная с места назначения to. Преобразует не более (from_end - from) элементов источника и сохраняет не более (to_end - to) элементов назначения.
Останавливается, если встречает персонажа, которого не может преобразовать. Он всегда оставляет from_next и to_next указатели , указывающие один за последним элементом успешно конвертированы. Если возвращает noconv, internT и externT имеют тот же тип, а преобразованная последовательность идентична входной последовательности [from, from_next). to_next установлен равным to, значение state не изменяется, и нет никаких изменений в значениях в [to, to_end).
codecvt Фаска , который используется basic_filebuf ([file.streams]) должна обладать свойством , что если
do_out(state, from, from_end, from_next, to, to_end, to_next)
вернется ok, где from != from_endтогда
do_out(state, from, from + 1, from_next, to, to_end, to_next)
также вернется ok, и что если
do_in(state, from, from_end, from_next, to, to_end, to_next)
вернется ok, где to != to_endтогда
do_in(state, from, from_end, from_next, to, to + 1, to_next)
также вернемся ok.236 [ Note: В результате операций с stateон может возвращать ok или partial и устанавливать from_next == from и to_next != to. ] — end note
Remarks: Его операции не state указаны. [ Note: Этот аргумент может использоваться, например, для поддержания состояния сдвига, для указания параметров преобразования (например, только счетчик) или для идентификации кэша смещений поиска. ] — end note
Returns: Значение перечисления, как показано в Табл 71.
Ценить | Имея в виду |
ok | завершил преобразование |
partial | не все исходные символы преобразованы |
error | обнаружил символ, [from, from_end) который не может преобразовать |
noconv | internT и externT одного типа, а входная последовательность идентична преобразованной последовательности |
Возвращаемое значение partialif (from_next == from_end)указывает, что либо целевая последовательность не поглотила все доступные элементы назначения, либо необходимы дополнительные исходные элементы, прежде чем можно будет создать другой элемент назначения.
result do_unshift(stateT& state, externT* to, externT* to_end, externT*& to_next) const;
Requires: (to <= to_end) четко очерченный и true; состояние инициализировано, если оно находится в начале последовательности, или равно результату преобразования предыдущих символов в последовательности.
Effects: Знаки, начинающиеся с to этого места, должны быть добавлены для завершения последовательности, когда текущее значение stateT задается state.237 Сохраняет не более (to_end - to) элементов назначения и оставляет to_next указатель, указывающий на один за последним успешно сохраненным элементом.
Returns: Значение перечисления, как показано в Табл 72.
Ценить | Имея в виду |
ok | завершил последовательность |
partial | пространство для более чем to_end - to целевых элементов требовалось для завершения последовательности с учетом значения state |
error | произошла неопределенная ошибка |
noconv | для этого не требуется прекращения state_type |
int do_encoding() const noexcept;
bool do_always_noconv() const noexcept;
Returns: true если do_in() и do_out() вернуться noconv для всех допустимых значений аргументов. codecvt<char, char, mbstate_t> возвращается true.
int do_length(stateT& state, const externT* from, const externT* from_end, size_t max) const;
Requires: (from <= from_end) четко определенные и true; state инициализируется, если оно находится в начале последовательности, или равно результату преобразования предыдущих символов в последовательности.
Effects: Влияние на state аргумент «как будто» она называется do_in(state, from, from_end, from, to, to+max, to) для to указывая на буфер , по крайней мере max элементов.
Returns: (from_next-from) где from_next - наибольшее значение в диапазоне, [from, from_end] такое, что последовательность значений в диапазоне [from, from_next) представляет max или меньше допустимых полных символов типа internT. Специализация codecvt<char, char, mbstate_t>возвращает меньшее из значений max и (from_end-from).
int do_max_length() const noexcept;
Returns: Максимальное значение, которое do_length(state, from, from_end, 1) может быть возвращено для любого допустимого диапазона [from, from_end) и stateT значения state. Специализация codecvt<char, char, mbstate_t>::do_max_length() возвращает 1.
Неформально это означает, что basic_filebuf предполагается, что отображение внутренних символов на внешние - от 1 до N: codecvt фасет, который используется, basic_filebuf должен иметь возможность переводить символы по одному внутреннему символу за раз.
Обычно это символы, в которые нужно вернуть состояние stateT().
Если encoding() уступает -1, то max_length() externT при создании одного internT символа может быть использовано больше элементов , а дополнительные externT элементы могут появиться в конце последовательности после тех, которые дают последний internT символ.
namespace std { template <class internT, class externT, class stateT> class codecvt_byname : public codecvt<internT, externT, stateT> { public: explicit codecvt_byname(const char*, size_t refs = 0); explicit codecvt_byname(const string&, size_t refs = 0); protected: ~codecvt_byname(); }; }
Классы num_get<> и num_put<> обрабатывают числовое форматирование и синтаксический анализ. Виртуальные функции предусмотрены для нескольких числовых типов. Реализации могут (но не обязаны) делегировать извлечение более мелких типов экстракторам для более крупных типов.239
Все спецификации функций членов для num_put и num_get в подразделах [category.numeric] применяются только к специализации , требуемой в таблицах 69 и 70 ([locale.category]), а именно num_get<char>, num_get<wchar_t>, num_get<C, InputIterator>, num_put<char>, num_put<wchar_t>, и num_put<C, OutputIterator>. Эти специализации относятся к ios_base& аргументу для спецификаций форматирования ([locale.categories]) и к его встроенному языку для numpunct<> фасета, чтобы идентифицировать все предпочтения числовой пунктуации, а также к ctype<> фасету для выполнения классификации символов.
Экстрактор и вставляют члены стандартного iostreams использования num_get<> и num_put<> функция - членов для форматирования и синтаксического анализа числовых значений ([istream.formatted.reqmts], [ostream.formatted.reqmts]).
"-1" Правильный синтаксический анализ , например, unsigned short требует, чтобы член-корреспондент 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.
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;
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: функция инициализирует локальные переменные через
fmtflags flags = str.flags(); fmtflags basefield = (flags & ios_base::basefield); fmtflags uppercase = (flags & ios_base::uppercase); fmtflags boolalpha = (flags & ios_base::boolalpha);
Для преобразования в целочисленный тип функция определяет спецификатор целочисленного преобразования, как указано в таблице 73. Стол заказан. То есть применяется первая строка, для которой выполнено условие.
Состояние | stdio эквивалент |
basefield == oct | %o |
basefield == hex | %X |
basefield == 0 | %i |
signed интегральный тип | %d |
unsigned интегральный тип | %u |
Для преобразований в плавающий тип спецификатором является %g.
Для преобразований void* в спецификатор есть %p.
При необходимости в спецификацию преобразования добавляется модификатор длины, как указано в таблице 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
namespace std { template <class charT, class OutputIterator = ostreambuf_iterator<charT>> class num_put : public locale::facet { public: using char_type = charT; using iter_type = OutputIterator; explicit num_put(size_t refs = 0); iter_type put(iter_type s, ios_base& f, char_type fill, bool v) const; iter_type put(iter_type s, ios_base& f, char_type fill, long v) const; iter_type put(iter_type s, ios_base& f, char_type fill, long long v) const; iter_type put(iter_type s, ios_base& f, char_type fill, unsigned long v) const; iter_type put(iter_type s, ios_base& f, char_type fill, unsigned long long v) const; iter_type put(iter_type s, ios_base& f, char_type fill, double v) const; iter_type put(iter_type s, ios_base& f, char_type fill, long double v) const; iter_type put(iter_type s, ios_base& f, char_type fill, const void* v) const; static locale::id id; protected: ~num_put(); virtual iter_type do_put(iter_type, ios_base&, char_type fill, bool v) const; virtual iter_type do_put(iter_type, ios_base&, char_type fill, long v) const; virtual iter_type do_put(iter_type, ios_base&, char_type fill, long long v) const; virtual iter_type do_put(iter_type, ios_base&, char_type fill, unsigned long) const; virtual iter_type do_put(iter_type, ios_base&, char_type fill, unsigned long long) const; virtual iter_type do_put(iter_type, ios_base&, char_type fill, double v) const; virtual iter_type do_put(iter_type, ios_base&, char_type fill, long double v) const; virtual iter_type do_put(iter_type, ios_base&, char_type fill, const void* v) const; }; }
Фасет num_put используется для форматирования числовых значений в последовательность символов, такую как поток.
iter_type put(iter_type out, ios_base& str, char_type fill, bool val) const;
iter_type put(iter_type out, ios_base& str, char_type fill, long val) const;
iter_type put(iter_type out, ios_base& str, char_type fill, long long val) const;
iter_type put(iter_type out, ios_base& str, char_type fill, unsigned long val) const;
iter_type put(iter_type out, ios_base& str, char_type fill, unsigned long long val) const;
iter_type put(iter_type out, ios_base& str, char_type fill, double val) const;
iter_type put(iter_type out, ios_base& str, char_type fill, long double val) const;
iter_type put(iter_type out, ios_base& str, char_type fill, const void* val) const;
iter_type do_put(iter_type out, ios_base& str, char_type fill, long val) const;
iter_type do_put(iter_type out, ios_base& str, char_type fill, long long val) const;
iter_type do_put(iter_type out, ios_base& str, char_type fill, unsigned long val) const;
iter_type do_put(iter_type out, ios_base& str, char_type fill, unsigned long long val) const;
iter_type do_put(iter_type out, ios_base& str, char_type fill, double val) const;
iter_type do_put(iter_type out, ios_base& str, char_type fill, long double val) const;
iter_type do_put(iter_type out, ios_base& str, char_type fill, const void* val) const;
Effects: Записывает символы в последовательность out, форматируя val по желанию. В следующем описании локальная переменная инициализируется с помощью:
locale loc = str.getloc();
Детали этой операции происходят в несколько этапов:
Этап 1. Определите спецификатор преобразования printf spec и определите символы, которые будут напечатаны с помощью printf ([c.files]) с учетом этого спецификатора преобразования для
printf(spec, val)
предполагая, что текущая локаль является "C" локалью.
Этап 2: Настройте представление путем преобразования каждого, char определенного на этапе 1, в a, charT используя преобразование и значения, возвращаемые членами use_facet<numpunct<charT>>(str.getloc())
Этап 3: Определите, где требуется заполнение.
Этап 4: Вставьте последовательность в файл out.
Этап 1. Первое действие этапа 1 - определить спецификатор преобразования. В таблицах, описывающих это определение, используются следующие локальные переменные
fmtflags flags = str.flags(); fmtflags basefield = (flags & (ios_base::basefield)); fmtflags uppercase = (flags & (ios_base::uppercase)); fmtflags floatfield = (flags & (ios_base::floatfield)); fmtflags showpos = (flags & (ios_base::showpos)); fmtflags showbase = (flags & (ios_base::showbase)); fmtflags showpoint = (flags & (ios_base::showpoint));
Все таблицы, используемые при описании этапа 1, заказаны. То есть применяется первая строка, для которой выполнено условие. Строка без условия является поведением по умолчанию, когда ни одна из предыдущих строк не применяется.
Для преобразования из целочисленного типа, отличного от символьного, функция определяет спецификатор целочисленного преобразования, как указано в таблице 75.
Состояние | stdio эквивалент |
basefield == ios_base::oct | %o |
(basefield == ios_base::hex) && !uppercase | %x |
(basefield == ios_base::hex) | %X |
для signed целого типа | %d |
для unsigned целого типа | %u |
Для преобразования из типа с плавающей запятой функция определяет спецификатор преобразования с плавающей запятой, как указано в таблице 76.
Состояние | stdio эквивалент |
floatfield == ios_base::fixed | %f |
floatfield == ios_base::scientific && !uppercase | %e |
floatfield == ios_base::scientific | %E |
floatfield == (ios_base::fixed | ios_base::scientific) && !uppercase | %a |
floatfield == (ios_base::fixed | ios_base::scientific) | %A |
!uppercase | %g |
otherwise | %G |
Для преобразований из целочисленного типа или типа с плавающей запятой к спецификатору преобразования добавляется модификатор длины, как указано в таблице 77.
Тип | Модификатор длины |
long | l |
long long | ll |
unsigned long | l |
unsigned long long | ll |
long double | L |
otherwise | none |
К спецификатору преобразования добавлены следующие необязательные дополнительные квалификаторы, как указано в таблице 78.
Тип (ы) | Состояние | stdio эквивалент |
интегральный тип | showpos | + |
showbase | # | |
тип с плавающей запятой | showpos | + |
showpoint | # |
Для преобразования из типа с плавающей точкой, если floatfield != (ios_base::fixed | ios_base::scientific), str.precision() определяются как точность в спецификации преобразования. В противном случае точность не указана.
Для преобразования из void* спецификатора есть %p.
Представления в конце этапа 1 состоят из char's, которые будут напечатаны вызовом printf(s, val) where s - спецификатор преобразования, определенный выше.
Этап 2: Любой символ, c кроме десятичной точки (.), Преобразуется в переходное charT отверстие. use_facet<ctype<charT>>(loc).widen( c )
Локальная переменная punct инициализируется через
const numpunct<charT>& punct = use_facet<numpunct<charT>>(str.getloc());
Для арифметических типов punct.thousands_sep() символы вставляются в последовательность, как определено значением, возвращаемым с punct.do_grouping() помощью метода, описанного в [facet.numpunct.virtuals]
Символы десятичной точки (.) Заменяются на punct.decimal_point()
Этап 3: локальная переменная инициализируется как
fmtflags adjustfield = (flags & (ios_base::adjustfield));
Расположение любой прокладки240 определяется по Табл 79.
Состояние | Место нахождения |
adjustfield == ios_base::left | подушечка после |
adjustfield == ios_base::right | колодка перед |
adjustfield == internal и знак встречается в представлении | блокнот после знака |
adjustfield == internal и представление после этапа 1 началось с 0x или 0X | проложить после x или X |
otherwise | колодка перед |
Если не str.width() равно нулю и количество символовcharTв последовательности после этапа 2 меньше чем str.width(), то fill в последовательность добавляется достаточное количество символов в позиции, указанной для заполнения, чтобы довести длину последовательности до str.width().
str.width(0) называется.
Этап 4: последовательность charTсимволов в конце этапа 3 выводится через
*out++ = c
iter_type do_put(iter_type out, ios_base& str, char_type fill, bool val) const;
Returns:
Если
(str.flags() & ios_base::boolalpha) == 0
возвращается
do_put(out, str, fill,
(int)val), иначе получает строку,
s
как если бы
string_type s = val ? use_facet<numpunct<charT>>(loc).truename() : use_facet<numpunct<charT>>(loc).falsename();
а затем вставляет каждый символ c в s переходное out отверстие *out++ = c и возвращает out.
Спецификация преобразования #o генерирует интерлиньяж, 0 который является not символом заполнения.
namespace std { template <class charT> class numpunct : public locale::facet { public: using char_type = charT; using string_type = basic_string<charT>; explicit numpunct(size_t refs = 0); char_type decimal_point() const; char_type thousands_sep() const; string grouping() const; string_type truename() const; string_type falsename() const; static locale::id id; protected: ~numpunct(); // virtual virtual char_type do_decimal_point() const; virtual char_type do_thousands_sep() const; virtual string do_grouping() const; virtual string_type do_truename() const; // for bool virtual string_type do_falsename() const; // for bool }; }
numpunct<> указывает числовую пунктуацию. Специализации, требуемые в Table 69 ([locale.category]), а именно numpunct<wchar_t> и numpunct<char>, предоставляют классические "C" числовые форматы, т. Е. Они содержат информацию, эквивалентную той, которая содержится в "C" локали или их аналогах из широких символов, как если бы она была получена при вызове widen.
Синтаксис для числовых форматов следующий, где digit представляет собой набор оснований системы счисления, указанный fmtflags значением аргумента, а thousands-sep и decimal-point являются результатами соответствующих numpunct<charT> членов. Целочисленные значения имеют формат:
integer ::= [sign] units sign ::= plusminus plusminus ::= '+' | '-' units ::= digits [thousands-sep units] digits ::= digit [digits]
и значения с плавающей запятой имеют:
floatval ::= [sign] units [decimal-point [digits]] [e [sign] digits] | [sign] decimal-point digits [e [sign] digits] e ::= 'e' | 'E'
где количество цифр между thousands-seps указано в do_grouping(). Для синтаксического анализа, если digits часть не содержит разделителей тысяч, ограничение группировки не применяется.
char_type decimal_point() const;
char_type thousands_sep() const;
string grouping() const;
string_type truename() const;
string_type falsename() const;
char_type do_decimal_point() const;
Returns: Символ для использования в качестве разделителя десятичной системы счисления. Требуемые специализации возвращаются '.' или L'.'.
char_type do_thousands_sep() const;
Returns: Символ для использования в качестве разделителя групп цифр. Требуемые специализации возвращаются ',' или L','.
string do_grouping() const;
Returns: Basic_string <char>, vec используемый как вектор целочисленных значений, в котором каждый элемент vec[i] представляет количество цифр241 в группе в позиции i, начиная с позиции 0 как самой правой группы. Если vec.size() <= i, номер такой же, как у группы (i - 1); если (i < 0 || vec[i] <= 0 || vec[i] == CHAR_MAX)размер группы цифр не ограничен.
string_type do_truename() const;
string_type do_falsename() const;
Таким образом, строка "\003" определяет группы по 3 цифры каждая и, "3" вероятно, указывает группы из 51 (!) Цифры каждая, потому что 51 - это значение ASCII для "3".
namespace std {
template <class charT>
class numpunct_byname : public numpunct<charT> {
// this class is specialized for char and wchar_t.
public:
using char_type = charT;
using string_type = basic_string<charT>;
explicit numpunct_byname(const char*, size_t refs = 0);
explicit numpunct_byname(const string&, size_t refs = 0);
protected:
~numpunct_byname();
};
}
namespace std { template <class charT> class collate : public locale::facet { public: using char_type = charT; using string_type = basic_string<charT>; explicit collate(size_t refs = 0); int compare(const charT* low1, const charT* high1, const charT* low2, const charT* high2) const; string_type transform(const charT* low, const charT* high) const; long hash(const charT* low, const charT* high) const; static locale::id id; protected: ~collate(); virtual int do_compare(const charT* low1, const charT* high1, const charT* low2, const charT* high2) const; virtual string_type do_transform(const charT* low, const charT* high) const; virtual long do_hash (const charT* low, const charT* high) const; }; }
Класс collate<charT> предоставляет функции для использования при сопоставлении (сравнении) и хешировании строк. Шаблон функции-члена языкового стандарта operator()использует фасет сопоставления, чтобы языковой стандарт действовал непосредственно в качестве аргумента предиката для стандартных алгоритмов (пункт [algorithms]) и контейнеров, работающих со строками. Применяются специализации, требуемые в таблице 69 ([locale.category]), а именно collate<char> и .collate<wchar_t> lexicographic ordering
int compare(const charT* low1, const charT* high1,
const charT* low2, const charT* high2) const;
string_type transform(const charT* low, const charT* high) const;
long hash(const charT* low, const charT* high) const;
int do_compare(const charT* low1, const charT* high1,
const charT* low2, const charT* high2) const;
Returns: 1 если первая строка больше второй, -1 если меньше, в противном случае ноль. Специализации, требуемые в Table 69 ([locale.category]), а именно collate<char> и collate<wchar_t>, реализуют lexicographical comparison.
string_type do_transform(const charT* low, const charT* high) const;
long do_hash(const charT* low, const charT* high) const;
Returns: Целочисленное значение, равное результату вызова hash() любой другой строки, для которой do_compare() возвращается 0 (равно) при передаче двух строк. [ Note: Вероятность того, что результат такой же, как у другой строки, которая не сравнивается с равной, должна быть очень маленькой, приближающейся (1.0/numeric_limits<unsigned long>::max()). ] — end note
Эта функция полезна, когда одна строка сравнивается со многими другими строками.
namespace std { template <class charT> class collate_byname : public collate<charT> { public: using string_type = basic_string<charT>; explicit collate_byname(const char*, size_t refs = 0); explicit collate_byname(const string&, size_t refs = 0); protected: ~collate_byname(); }; }
Шаблоны time_get<charT, InputIterator> и time_put<charT, OutputIterator> обеспечивают форматирование и анализ даты и времени. Все спецификации функций-членов для time_put и time_get в подпунктах [category.time] применимы только к специализациям, требуемым в таблицах 69 и 70 ([locale.category]). Их члены используют их ios_base&, ios_base::iostate&и fill аргументы , как описано в [locale.categories], и ctype<> огранку, чтобы определить детали форматирования.
namespace std { class time_base { public: enum dateorder { no_order, dmy, mdy, ymd, ydm }; }; template <class charT, class InputIterator = istreambuf_iterator<charT>> class time_get : public locale::facet, public time_base { public: using char_type = charT; using iter_type = InputIterator; explicit time_get(size_t refs = 0); dateorder date_order() const { return do_date_order(); } iter_type get_time(iter_type s, iter_type end, ios_base& f, ios_base::iostate& err, tm* t) const; iter_type get_date(iter_type s, iter_type end, ios_base& f, ios_base::iostate& err, tm* t) const; iter_type get_weekday(iter_type s, iter_type end, ios_base& f, ios_base::iostate& err, tm* t) const; iter_type get_monthname(iter_type s, iter_type end, ios_base& f, ios_base::iostate& err, tm* t) const; iter_type get_year(iter_type s, iter_type end, ios_base& f, ios_base::iostate& err, tm* t) const; iter_type get(iter_type s, iter_type end, ios_base& f, ios_base::iostate& err, tm* t, char format, char modifier = 0) const; iter_type get(iter_type s, iter_type end, ios_base& f, ios_base::iostate& err, tm* t, const char_type* fmt, const char_type* fmtend) const; static locale::id id; protected: ~time_get(); virtual dateorder do_date_order() const; virtual iter_type do_get_time(iter_type s, iter_type end, ios_base&, ios_base::iostate& err, tm* t) const; virtual iter_type do_get_date(iter_type s, iter_type end, ios_base&, ios_base::iostate& err, tm* t) const; virtual iter_type do_get_weekday(iter_type s, iter_type end, ios_base&, ios_base::iostate& err, tm* t) const; virtual iter_type do_get_monthname(iter_type s, iter_type end, ios_base&, ios_base::iostate& err, tm* t) const; virtual iter_type do_get_year(iter_type s, iter_type end, ios_base&, ios_base::iostate& err, tm* t) const; virtual iter_type do_get(iter_type s, iter_type end, ios_base& f, ios_base::iostate& err, tm* t, char format, char modifier) const; }; }
time_get используется для синтаксического анализа последовательности символов, извлечения компонентов времени или даты в struct tm объект. Каждый get член анализирует формат, созданный соответствующим описателем формата time_put<>::put. Если анализируемая последовательность соответствует правильному формату, соответствующие члены struct tm аргумента устанавливаются в значения, используемые для создания последовательности; в противном случае либо сообщается об ошибке, либо присваиваются неопределенные значения.243
Если конечный итератор будет достигнут в процессе синтаксического анализа с помощью любого из get() функций элементов, множества членов ios_base::eofbit в err.
Другими словами, подтверждение пользователя требуется для надежного анализа введенных пользователем даты и времени, но сгенерированные компьютером форматы могут быть надежно проанализированы. Это позволяет синтаксическим анализаторам агрессивно интерпретировать пользовательские варианты стандартных форматов.
dateorder date_order() const;
iter_type get_time(iter_type s, iter_type end, ios_base& str,
ios_base::iostate& err, tm* t) const;
iter_type get_date(iter_type s, iter_type end, ios_base& str,
ios_base::iostate& err, tm* t) const;
iter_type get_weekday(iter_type s, iter_type end, ios_base& str,
ios_base::iostate& err, tm* t) const;
iter_type get_monthname(iter_type s, iter_type end, ios_base& str,
ios_base::iostate& err, tm* t) const;
iter_type get_year(iter_type s, iter_type end, ios_base& str,
ios_base::iostate& err, tm* t) const;
iter_type get(iter_type s, iter_type end, ios_base& f, ios_base::iostate& err,
tm* t, char format, char modifier = 0) const;
iter_type get(iter_type s, iter_type end, ios_base& f, ios_base::iostate& err,
tm* t, const char_type* fmt, const char_type* fmtend) const;
Effects: Функция начинается с оценки err = ios_base::goodbit. Затем он входит в цикл, считывая ноль или более символов s на каждой итерации. Если ниже не указано иное, цикл завершается, когда выполняется первое из следующих условий:
Выражение fmt == fmtend оценивается как true.
Выражение err == ios_base::goodbit оценивается как false.
Выражение s == end оценивается как true, и в этом случае вычисляется функция err = ios_base::eofbit | ios_base::failbit.
Следующий элемент fmt равен '%', необязательно за ним следует символ-модификатор, за которым следует символ-спецификатор преобразования, formatвместе формируя спецификацию преобразования, действительную для функции ISO / IEC 9945 strptime. Если количество элементов в диапазоне [fmt, fmtend) недостаточно, чтобы однозначно определить, является ли спецификация преобразования полной и действительной, функция выполняет оценку err = ios_base::failbit. В противном случае, функция вычисляет s = do_get(s, end, f, err, t, format, modifier), где значение modifier IS , '\0' когда дополнительный модификатор отсутствует в спецификации преобразования. Если err == ios_base::goodbit удерживается после вычисления выражения, функция увеличивается fmt до точки сразу за концом спецификации преобразования и продолжает цикл.
Выражение isspace(*fmt, f.getloc()) вычисляется до true, и в этом случае функция сначала увеличивается fmt до тех пор, пока не будет fmt == fmtend || !isspace(*fmt, f.getloc()) вычислено значение true, затем продвигается, s пока не s == end || !isspace(*s, f.getloc()) будет true, и, наконец, возобновит цикл.
Следующий считанный символ s соответствует элементу, на который указывает fmt регистр при сравнении, и в этом случае функция оценивает ++fmt, ++s и продолжает цикл. В противном случае функция оценивает err = ios_base::failbit.
[ Note: Функция использует ctype<charT> фасет, установленный в fлокали, для определения допустимых пробельных символов. Не указано, каким образом функция выполняет сравнение без учета регистра и учитываются ли при этом многосимвольные последовательности. ] — end note
dateorder do_date_order() const;
Returns: Значение перечисления, указывающее предпочтительный порядок компонентов для тех форматов даты, которые состоят из дня, месяца и года.244 Возвращает, no_order если формат даты, заданный параметром, 'x' содержит другие переменные компоненты (например, день по юлианскому календарю, номер недели, день недели).
iter_type do_get_time(iter_type s, iter_type end, ios_base& str,
ios_base::iostate& err, tm* t) const;
Effects: Читает символы, начиная с, s пока он не извлечет эти struct tm элементы, и оставшиеся символы формата, используемые time_put<>::put для создания формата, указанного в "%H:%M:%S", или до тех пор, пока он не обнаружит ошибку или конец последовательности.
Returns: Итератор, указывающий сразу за последним символом, который может быть признан частью допустимого времени.
iter_type do_get_date(iter_type s, iter_type end, ios_base& str,
ios_base::iostate& err, tm* t) const;
Effects: Считывает символы, начинающиеся с, s до тех пор, пока не будут извлечены эти struct tm элементы и оставшиеся символы формата, используемые time_put<>::put для создания одного из следующих форматов, или пока не возникнет ошибка. Формат зависит от значения, возвращаемого, date_order() как показано в таблице 80.
date_order() | Формат |
no_order | "%m%d%y" |
dmy | "%d%m%y" |
mdy | "%m%d%y" |
ymd | "%y%m%d" |
ydm | "%y%d%m" |
Returns: Итератор, указывающий сразу за последним символом, который может быть признан частью допустимой даты.
iter_type do_get_weekday(iter_type s, iter_type end, ios_base& str,
ios_base::iostate& err, tm* t) const;
iter_type do_get_monthname(iter_type s, iter_type end, ios_base& str,
ios_base::iostate& err, tm* t) const;
Effects: Читает символы, начинающиеся с, s пока не будет извлечено (возможно, сокращенное) название дня недели или месяца. Если он находит сокращение, за которым следуют символы, которые могут соответствовать полному имени, он продолжает чтение, пока не совпадет с полным именем или не завершится ошибкой. Соответственно, он устанавливает соответствующий struct tm член.
Returns: Итератор, указывающий сразу за последним символом, распознанным как часть допустимого имени.
iter_type do_get_year(iter_type s, iter_type end, ios_base& str,
ios_base::iostate& err, tm* t) const;
Returns: Итератор, указывающий сразу за последним символом, распознанным как часть допустимого идентификатора года.
iter_type do_get(iter_type s, iter_type end, ios_base& f,
ios_base::iostate& err, tm* t, char format, char modifier) const;
Effects: Функция начинается с оценки err = ios_base::goodbit. Затем он считывает символы , начиная с s до тех пор, пока не обнаружит ошибку, или до тех пор, пока не добыл и назначены те struct tm члены, и все оставшиеся символы формата, соответствующий директиве преобразования , подходящей для 9945 функции ISO / IEC strptime, формируется путем конкатенации '%', на modifier характер, когда не NUL, и format персонаж. Когда конкатенация не дает полной допустимой директивы, функция оставляет объект, на который указывает t без изменений, и выполняет оценку err |= ios_base::failbit. Когда s == end оценивается true после чтения символа, функция оценивает err |= ios_base::eofbit.
Для сложных директив преобразования , такие как %c, %x, или %X, или директив , которые включают дополнительные модификаторы E или O, когда функция не может однозначно определить некоторые или все struct tm элементы из входной последовательности [s, end), он оценивает err |= ios_base::eofbit. В таких случаях значения этих struct tm элементов не указаны и могут выходить за пределы допустимого диапазона.
Remarks: Не указано, будут ли многократные вызовы do_get() с адресом одного и того же struct tm объекта обновлять текущее содержимое объекта или просто перезаписывать его элементы. Переносимые программы должны обнулить объект перед вызовом функции.
Returns: Итератор, указывающий сразу за последним символом, который, возможно, распознается как часть допустимой входной последовательности для заданных format и modifier.
Эта функция предназначена только для удобства, для распространенных форматов и может возвращаться no_order в допустимых региональных стандартах.
namespace std { template <class charT, class InputIterator = istreambuf_iterator<charT>> class time_get_byname : public time_get<charT, InputIterator> { public: using dateorder = time_base::dateorder; using iter_type = InputIterator; explicit time_get_byname(const char*, size_t refs = 0); explicit time_get_byname(const string&, size_t refs = 0); protected: ~time_get_byname(); }; }
namespace std {
template <class charT, class OutputIterator = ostreambuf_iterator<charT>>
class time_put : public locale::facet {
public:
using char_type = charT;
using iter_type = OutputIterator;
explicit time_put(size_t refs = 0);
// the following is implemented in terms of other member functions.
iter_type put(iter_type s, ios_base& f, char_type fill, const tm* tmb,
const charT* pattern, const charT* pat_end) const;
iter_type put(iter_type s, ios_base& f, char_type fill,
const tm* tmb, char format, char modifier = 0) const;
static locale::id id;
protected:
~time_put();
virtual iter_type do_put(iter_type s, ios_base&, char_type, const tm* t,
char format, char modifier) const;
};
}
iter_type put(iter_type s, ios_base& str, char_type fill, const tm* t,
const charT* pattern, const charT* pat_end) const;
iter_type put(iter_type s, ios_base& str, char_type fill, const tm* t,
char format, char modifier = 0) const;
Effects: Первая форма проходит через последовательность от pattern до pat_end, определяя символы, которые являются частью последовательности форматирования. Каждый символ, который не является частью последовательности форматирования, записывается s немедленно, и каждая последовательность форматирования, как она идентифицирована, приводит к вызову do_put; таким образом, элементы формата и другие символы чередуются в выводе в том порядке, в котором они появляются в шаблоне. Последовательности форматов идентифицируются путем преобразования каждого символа c в char значение, как если бы ct.narrow(c, 0), где ct - ссылка, из которой нужно ctype<charT> получить str.getloc(). Первый символ каждой последовательности равен '%', за ним следует необязательный символ-модификатор и символ-спецификатор mod245 формата, spec как определено для функции strftime. Если символ-модификатор отсутствует, mod равен нулю. Для каждой идентифицированной допустимой последовательности форматов вызывается do_put(s, str, fill, t, spec, mod).
[ Аргумент может быть использован в реализации определенных форматов или дифференцирования. Разумным значением по умолчанию для этого аргумента является пробел. ] Note: fill — end note
Хотя язык программирования C не определяет никаких модификаторов, большинство поставщиков это делают.
iter_type do_put(iter_type s, ios_base&, char_type fill, const tm* t,
char format, char modifier) const;
Effects: Форматирует содержимое параметра t в символы, помещенные в выходную последовательность s. Форматирование управляется параметрами format и modifierинтерпретируется идентично спецификаторам формата в строковом аргументе стандартной библиотечной функции strftime()246, за исключением того, что последовательность символов, созданная для тех спецификаторов, которые описаны как зависящие от локали C, вместо этого определяется реализацией.247
Returns: Итератор, указывающий сразу после последнего созданного символа. [ Аргумент может быть использован в реализации определенных форматов или дифференцирования. Разумным значением по умолчанию для этого аргумента является пробел. ] Note: fill — end note
Интерпретация modifier аргумента определяется реализацией, но должна соответствовать соглашениям POSIX.
Реализациям рекомендуется ссылаться на другие стандарты, такие как POSIX, для этих определений.
namespace std { template <class charT, class OutputIterator = ostreambuf_iterator<charT>> class time_put_byname : public time_put<charT, OutputIterator> { public: using char_type = charT; using iter_type = OutputIterator; explicit time_put_byname(const char*, size_t refs = 0); explicit time_put_byname(const string&, size_t refs = 0); protected: ~time_put_byname(); }; }
Эти шаблоны обрабатывают денежные форматы. Параметр шаблона указывает, какой формат валюты следует использовать: местный или международный.
Все спецификации функций-членов для money_put и money_get в подпунктах [category.monetary] применимы только к специализациям, требуемым в таблицах 69 и 70 ([locale.category]). Их члены используют их ios_base&, ios_base::iostate&и fill аргументы , как описано в [locale.categories], и moneypunct<> и ctype<> грани, чтобы определить детали форматирования.
namespace std { template <class charT, class InputIterator = istreambuf_iterator<charT>> class money_get : public locale::facet { public: using char_type = charT; using iter_type = InputIterator; using string_type = basic_string<charT>; explicit money_get(size_t refs = 0); iter_type get(iter_type s, iter_type end, bool intl, ios_base& f, ios_base::iostate& err, long double& units) const; iter_type get(iter_type s, iter_type end, bool intl, ios_base& f, ios_base::iostate& err, string_type& digits) const; static locale::id id; protected: ~money_get(); virtual iter_type do_get(iter_type, iter_type, bool, ios_base&, ios_base::iostate& err, long double& units) const; virtual iter_type do_get(iter_type, iter_type, bool, ios_base&, ios_base::iostate& err, string_type& digits) const; }; }
iter_type get(iter_type s, iter_type end, bool intl,
ios_base& f, ios_base::iostate& err,
long double& quant) const;
iter_type get(s, iter_type end, bool intl, ios_base&f,
ios_base::iostate& err, string_type& quant) const;
iter_type do_get(iter_type s, iter_type end, bool intl,
ios_base& str, ios_base::iostate& err,
long double& units) const;
iter_type do_get(iter_type s, iter_type end, bool intl,
ios_base& str, ios_base::iostate& err,
string_type& digits) const;
Effects: Считывает символы из, s чтобы проанализировать и построить денежное значение в соответствии с форматом, указаннымmoneypunct<charT, Intl> ссылкой на фасет, mp и отображением символов, указаннымctype<charT> ссылкой на фасет, ct полученной из языкового стандарта, возвращенного str.getloc(), и str.flags(). Если действительная последовательность распознана, не изменяется err; в противном случае устанавливается err значение (err|str.failbit)или, (err|str.failbit|str.eofbit) если больше нет доступных символов, и не изменяется units или digits. Использует шаблон, возвращенный mp.neg_format() для анализа всех значений. Результат возвращается как целое значение, хранящееся в, units или как последовательность цифр, которой может предшествовать знак минус (как результат, ct.widen(c) где c есть '-' или в диапазоне от '0' до '9', включительно), сохраненный в digits. [ Example: Последовательность $1,056.23 в общей местности Соединенных Штатов дало бы, по units, 105623, или, digits, "105623". ] Если указывает, что разделители тысяч не разрешены, любые такие символы не читаются, и синтаксический анализ завершается в точке, где они появляются впервые. В противном случае разделители тысяч не являются обязательными; если они присутствуют, они проверяются на правильность размещения только после того, как будут прочитаны все компоненты формата. — end example mp.grouping()
Если money_base::space или money_base::none отображается как последний элемент в шаблоне формата, пробелы не используются. В противном случае, где money_base::space встречается в любом из начальных элементов шаблона формата, требуется по крайней мере один символ пробела. Если money_base::none присутствует в любом из начальных элементов шаблона формата, пробелы разрешены, но не обязательны. Если задано значение (str.flags() & str.showbase) false, символ валюты является необязательным и используется только в том случае, если для завершения формата необходимы другие символы; в противном случае требуется символ валюты.
Если первый символ (если есть) в строке, pos возвращаемой mp.positive_sign() илиneg возвращенной строкой , mp.negative_sign() распознается в позиции, указанной sign в шаблоне формата, он используется, и любые оставшиеся символы в строке требуются после всех других компонентов формата. [ Example: Если showbase выключен, то для neg значения "()" и символа валютной "L", в потребляется; но если есть , то in не потребляется. ] Если или пусто, компонент знака является необязательным, и если знак не обнаружен, результат получает знак, соответствующий источнику пустой строки. В противном случае символ в указанной позиции должен соответствовать первому символу или , и результат получает соответствующий знак. Если первый символ равен первому символу или обе строки пусты, результат получает положительный знак. "(100 L)" "L" neg "-" "L" "-100 L" — end example posnegposnegposneg
Цифры в числовом денежном компоненте извлекаются и помещаются в digitsили в символьный буфер buf1 для преобразования для получения значения unitsв том порядке, в котором они появляются, с предшествующим знаком минус тогда и только тогда, когда результат отрицательный. Значение units создается, как если бы248
for (int i = 0; i < n; ++i) buf2[i] = src[find(atoms, atoms+sizeof(src), buf1[i]) - atoms]; buf2[n] = 0; sscanf(buf2, "%Lf", &units);
где n - количество символов, помещенных в buf1, buf2 - символьный буфер, а значения src и atoms определяются как если бы
static const char src[] = "0123456789-"; charT atoms[sizeof(src)]; ct.widen(src, src + sizeof(src) - 1, atoms);
Returns: Итератор, указывающий сразу за последним символом, признанным частью допустимой денежной величины.
Семантика здесь отличается от ct.narrow.
namespace std { template <class charT, class OutputIterator = ostreambuf_iterator<charT>> class money_put : public locale::facet { public: using char_type = charT; using iter_type = OutputIterator; using string_type = basic_string<charT>; explicit money_put(size_t refs = 0); iter_type put(iter_type s, bool intl, ios_base& f, char_type fill, long double units) const; iter_type put(iter_type s, bool intl, ios_base& f, char_type fill, const string_type& digits) const; static locale::id id; protected: ~money_put(); virtual iter_type do_put(iter_type, bool, ios_base&, char_type fill, long double units) const; virtual iter_type do_put(iter_type, bool, ios_base&, char_type fill, const string_type& digits) const; }; }
iter_type put(iter_type s, bool intl, ios_base& f, char_type fill,
long double quant) const;
iter_type put(iter_type s, bool intl, ios_base& f, char_type fill,
const string_type& quant) const;
iter_type do_put(iter_type s, bool intl, ios_base& str,
char_type fill, long double units) const;
iter_type do_put(iter_type s, bool intl, ios_base& str,
char_type fill, const string_type& digits) const;
Effects: Записывает символы в s соответствии с форматом, указаннымmoneypunct<charT, Intl> ссылкой на фасет, mp и отображением символов, указаннымctype<charT> ссылкой на фасет, ct полученной из языкового стандарта, возвращаемого параметрами str.getloc(), и str.flags(). Аргумент units преобразуется в последовательность широких символов, как если бы
ct.widen(buf1, buf1 + sprintf(buf1, "%.0Lf", units), buf2)
для символьных буферов buf1 и buf2. Если первый символ в digits или buf2 равен ct.widen('-'), то шаблон, используемый для форматирования, является результатом mp.neg_format(); в противном случае узор является результатом mp.pos_format(). Цифровые символы записываются с вкраплениями разделителей тысяч и десятичной точки, указанных в формате, в том порядке, в котором они появляются (после необязательного ведущего знака минус) в digits или buf2. В digitsиспользуются только необязательный начальный знак минус и непосредственно следующие за ним цифровые символы (согласно классификации ct); любые завершающие символы (включая цифры, появляющиеся после нецифрового символа) игнорируются. Звонки str.width(0).
Remarks: Символ валюты генерируется тогда и только тогда, когда он не (str.flags() & str.showbase) равен нулю. Если количество символов, сгенерированных для указанного формата, меньше значения, возвращаемогоstr.width() функцией при входе в функцию, то копии fill вставляются по мере необходимости для заполнения до указанной ширины. Для значения, af равного (str.flags() & str.adjustfield), если (af == str.internal) есть true, символы заполнения помещаются там, где none или space появляются в шаблоне форматирования; в противном случае, если (af == str.left) есть true, они помещаются после других символов; в противном случае они помещаются перед другими символами. [ Note: Возможно, с некоторыми комбинациями шаблонов формата и значений флагов, чтобы произвести вывод, который не может быть проанализирован с использованием num_get<>::get. ] — end note
namespace std { class money_base { public: enum part { none, space, symbol, sign, value }; struct pattern { char field[4]; }; }; template <class charT, bool International = false> class moneypunct : public locale::facet, public money_base { public: using char_type = charT; using string_type = basic_string<charT>; explicit moneypunct(size_t refs = 0); charT decimal_point() const; charT thousands_sep() const; string grouping() const; string_type curr_symbol() const; string_type positive_sign() const; string_type negative_sign() const; int frac_digits() const; pattern pos_format() const; pattern neg_format() const; static locale::id id; static const bool intl = International; protected: ~moneypunct(); virtual charT do_decimal_point() const; virtual charT do_thousands_sep() const; virtual string do_grouping() const; virtual string_type do_curr_symbol() const; virtual string_type do_positive_sign() const; virtual string_type do_negative_sign() const; virtual int do_frac_digits() const; virtual pattern do_pos_format() const; virtual pattern do_neg_format() const; }; }
moneypunct<> Фасет определяет денежные параметры форматирования , используемые money_get<> и money_put<>. Денежный формат представляет собой последовательность из четырех компонентов, задается pattern значением p, таким образом, что part значение static_cast<part>(p.field[i]) определяет iй компонент формата249 В field члене pattern объекта, каждое значении symbol, sign, value, и или space или none появляется ровно один раз. Значение none, если оно присутствует, не является первым; значение space, если оно есть, не является ни первым, ни последним.
В тех местах, где none или spaceпоявляется, в формате разрешены пробелы, кроме тех, где они none появляются в конце, и в этом случае пробелы не допускаются. Значение space указывает, что в этой позиции требуется хотя бы один пробел. Если symbol появляется, последовательность символов, возвращаемая curr_symbol() функцией, разрешена и может быть обязательной. Тамsign , где появляется, требуется первая (если есть) из последовательности символов, возвращаемых функцией positive_sign() или negative_sign()(соответственно, поскольку денежное значение неотрицательно или отрицательно). Любые оставшиеся символы знаковой последовательности требуются после всех остальных компонентов формата. Где value появляется, требуется абсолютное числовое значение в денежном выражении.
Формат числового денежного значения - десятичное число:
value ::= units [ decimal-point [ digits ]] | decimal-point digits
если frac_digits() возвращает положительное значение, или
value ::= units
иначе. Этот символ decimal-point указывает на символ, возвращаемый функцией decimal_point(). Остальные символы определены следующим образом:
units ::= digits [ thousands-sep units ] digits ::= adigit [ digits ]
В описании синтаксиса, символ adigit является любым из значений ct.widen(c) для c в диапазоне '0' через '9', включительно, и ct является ссылкой типа ,const ctype<charT>& полученным , как описано в определениях money_get<> и money_put<>. Символ thousands-sep - это символ, возвращаемый функцией thousands_sep(). Используемый пробел - это значение ct.widen(' '). Символы пробела - это те символы,c для которых выполняется ci.is(space, c) возврат true. Количество цифр, необходимых после десятичной точки (если есть), в точности равно значению, возвращаемому функцией frac_digits().
Размещение символов-разделителей тысяч (если есть) определяется значением, возвращаемым grouping(), определяемым идентично члену numpunct<>::do_grouping().
Массив char, а не массив part, указан pattern::field исключительно для эффективности.
charT decimal_point() const; charT thousands_sep() const; string grouping() const; string_type curr_symbol() const; string_type positive_sign() const; string_type negative_sign() const; int frac_digits() const; pattern pos_format() const; pattern neg_format() const;
charT do_decimal_point() const;
charT do_thousands_sep() const;
string do_grouping() const;
string_type do_curr_symbol() const;
string_type do_positive_sign() const;
string_type do_negative_sign() const;
int do_frac_digits() const;
pattern do_pos_format() const;
pattern do_neg_format() const;
Returns: В специализации требуемая в таблице 70 ([locale.category]), а именно moneypunct<char>, moneypunct<wchar_t>, moneypunct<char, true>, и moneypunct<wchar_t, true>, возвращает объект типа pattern инициализируется { symbol, sign, none, value }.256
В обычных регионах США это так '.'.
В обычных регионах США это так ','.
Чтобы указать группировку по 3 с, значение равно "\003" not "3".
Для международных специализаций (второй параметр шаблона true) это обычно четыре символа, обычно три буквы и пробел.
Обычно это пустая строка.
В обычных регионах США это 2.
Обратите внимание, что международный символ, возвращаемый функцией, do_curr_sym() обычно сам содержит пробел; например "USD ",.
namespace std { template <class charT, bool Intl = false> class moneypunct_byname : public moneypunct<charT, Intl> { public: using pattern = money_base::pattern; using string_type = basic_string<charT>; explicit moneypunct_byname(const char*, size_t refs = 0); explicit moneypunct_byname(const string&, size_t refs = 0); protected: ~moneypunct_byname(); }; }
namespace std {
class messages_base {
public:
using catalog = unspecified signed integer type;
};
template <class charT>
class messages : public locale::facet, public messages_base {
public:
using char_type = charT;
using string_type = basic_string<charT>;
explicit messages(size_t refs = 0);
catalog open(const basic_string<char>& fn, const locale&) const;
string_type get(catalog c, int set, int msgid,
const string_type& dfault) const;
void close(catalog c) const;
static locale::id id;
protected:
~messages();
virtual catalog do_open(const basic_string<char>&, const locale&) const;
virtual string_type do_get(catalog, int set, int msgid,
const string_type& dfault) const;
virtual void do_close(catalog) const;
};
}
Значения типа messages_base::catalog могут использоваться в качестве аргументов для членов get и close могут быть получены только путем вызова member open.
catalog open(const basic_string<char>& name, const locale& loc) const;
string_type get(catalog cat, int set, int msgid, const string_type& dfault) const;
void close(catalog cat) const;
catalog do_open(const basic_string<char>& name, const locale& loc) const;
Remarks: Аргумент locale loc используется для преобразования кода набора символов при извлечении сообщений, если это необходимо.
string_type do_get(catalog cat, int set, int msgid, const string_type& dfault) const;
void do_close(catalog cat) const;
namespace std { template <class charT> class messages_byname : public messages<charT> { public: using catalog = messages_base::catalog; using string_type = basic_string<charT>; explicit messages_byname(const char*, size_t refs = 0); explicit messages_byname(const string&, size_t refs = 0); protected: ~messages_byname(); }; }
Программа на C ++ может определять фасеты, которые должны быть добавлены к языку и использоваться так же, как встроенные фасеты. Для того, чтобы создать новый интерфейс фасетки, программа C ++ просто вывести из locale::facet класса , содержащего статический член: static locale::id id.
[ Note: Шаблоны функций-членов языкового стандарта проверяют его тип и класс хранения. ] — end note
[ Example: Традиционная глобальная локализация по-прежнему проста:
#include <iostream> #include <locale> int main(int argc, char** argv) { using namespace std; locale::global(locale("")); // set the global locale // imbue it on all the std streams cin.imbue(locale()); cout.imbue(locale()); cerr.imbue(locale()); wcin.imbue(locale()); wcout.imbue(locale()); wcerr.imbue(locale()); return MyObject(argc, argv).doit(); }
— end example ]
[ Example: Возможна большая гибкость:
#include <iostream>
#include <locale>
int main() {
using namespace std;
cin.imbue(locale("")); // the user's preferred locale
cout.imbue(locale::classic());
double f;
while (cin >> f) cout << f << endl;
return (cin.fail() != 0);
}
В европейской локали с вводом 3.456,78вывод 3456.78. ] — end example
Это может быть важно даже для простых программ, которым может потребоваться запись файла данных в фиксированном формате, независимо от предпочтений пользователя.
[ Example: Вот пример использования локалей в интерфейсе библиотеки.
// file: Date.h
#include <iosfwd>
#include <string>
#include <locale>
class Date {
public:
Date(unsigned day, unsigned month, unsigned year);
std::string asString(const std::locale& = std::locale());
};
std::istream& operator>>(std::istream& s, Date& d);
std::ostream& operator<<(std::ostream& s, Date d);
Первый является аргументом по умолчанию в Date::asString(), где по умолчанию используется глобальный (предположительно предпочтительный для пользователя) языковой стандарт.
Второй - в операторах << и >>, где локаль «путешествует автостопом» на другом объекте, в данном случае на потоке, до точки, где это необходимо.
// file: Date.C #include "Date" // includes <ctime> #include <sstream> std::string Date::asString(const std::locale& l) { using namespace std; ostringstream s; s.imbue(l); s << *this; return s.str(); } std::istream& operator>>(std::istream& s, Date& d) { using namespace std; istream::sentry cerberos(s); if (cerberos) { ios_base::iostate err = goodbit; struct tm t; use_facet<time_get<char>>(s.getloc()).get_date(s, 0, s, err, &t); if (!err) d = Date(t.tm_day, t.tm_mon + 1, t.tm_year + 1900); s.setstate(err); } return s; }
— end example ]
Объект языкового стандарта может быть расширен новым аспектом, просто создав его с экземпляром класса, производного от locale::facet. Единственный членid, который должна определять программа C ++, - это статический член , который идентифицирует интерфейс вашего класса как новый аспект.
[ Example: Классификация японских иероглифов:
// file: <jctype> #include <locale> namespace My { using namespace std; class JCtype : public locale::facet { public: static locale::id id; // required for use as a new locale facet bool is_kanji (wchar_t c) const; JCtype() { } protected: ~JCtype() { } }; } // file: filt.C #include <iostream> #include <locale> #include "jctype" // above std::locale::id My::JCtype::id; // the static JCtype member declared above. int main() { using namespace std; using wctype = ctype<wchar_t>; locale loc(locale(""), // the user's preferred locale ... new My::JCtype); // and a new feature ... wchar_t c = use_facet<wctype>(loc).widen('!'); if (!use_facet<My::JCtype>(loc).is_kanji(c)) cout << "no it isn't!" << endl; }
[ Example: Заменить существующий фасет еще проще. Код не определяет член, id потому что он повторно использует numpunct<charT> интерфейс фасета:
// file: my_bool.C #include <iostream> #include <locale> #include <string> namespace My { using namespace std; using cnumpunct = numpunct_byname<char>; class BoolNames : public cnumpunct { protected: string do_truename() const { return "Oui Oui!"; } string do_falsename() const { return "Mais Non!"; } ~BoolNames() { } public: BoolNames(const char* name) : cnumpunct(name) { } }; } int main(int argc, char** argv) { using namespace std; // make the user's preferred locale, except for... locale loc(locale(""), new My::BoolNames("")); cout.imbue(loc); cout << boolalpha << "Any arguments today? " << (argc > 1) << endl; }
— end example ]
namespace std { struct lconv; char* setlocale(int category, const char* locale); lconv* localeconv(); } #define NULL see [support.types.nullptr] #define LC_ALL see below #define LC_COLLATE see below #define LC_CTYPE see below #define LC_MONETARY see below #define LC_NUMERIC see below #define LC_TIME see below
Содержание и значение заголовка <clocale> такие же , как заголовок стандартной библиотеки C <locale.h>.
Вызов функции setlocale может вызвать гонку данных ([res.on.data.races]) с другими вызовами setlocale или с вызовами функций, перечисленных в таблице 81.
См. Также: ISO C 7.11.
fprintf | isprint | iswdigit | localeconv | tolower |
fscanf | ispunct | iswgraph | mblen | toupper |
isalnum | isspace | iswlower | mbstowcs | towlower |
isalpha | isupper | iswprint | mbtowc | towupper |
isblank | iswalnum | iswpunct | setlocale | wcscoll |
iscntrl | iswalpha | iswspace | strcoll | wcstod |
isdigit | iswblank | iswupper | strerror | wcstombs |
isgraph | iswcntrl | iswxdigit | strtod | wcsxfrm |
islower | iswctype | isxdigit | strxfrm | wctomb |