Манипуляторы<iostream>очень полезны, но когда мы создаем сообщения для пользователя, иногда нам нужно что-то вроде старого доброго<printf>или<boost::format>.
К сожалению<boost::format>имеет несколько ограничений в контексте локализации:
- Он отображает все параметры, используя глобальную локализацию, а не целевую
ostreamлокализацию. Например:
std::locale::global"en_US.UTF-8"];
output.imbue"de_DE.UTF-8"]]
Это означает, что на выходе будет написано «1,234.235», а не «1.234,234», что ожидается для локализации «de_DE».
This would write "1,234.235" to output, instead of the "1.234,234" that is expected for "de_DE" locale[ORIG_END] -->
- Он ничего не знает о новом проекте. Локальные манипуляторы.
- Синтаксис
printf-likeочень ограничен для форматирования сложных локализованных данных, не позволяя форматировать даты, время или валюты.
Так появился новый классboost::locale::format. Например:
wcout <<
wformat(L
"Today {1,date} I would meet {2} at home") %
time(0) % name <<endl;
Каждый спецификатор формата заключен в<{}>скобки, отделен запятой" и может иметь дополнительную опцию после символа равенства "=". Это может быть простой текст ASCII или одноцитированный локализованный текст. Если в текст должна быть вставлена одноцита, она может быть представлена парой одноцитатных символов.
Вот пример строки формата:
"Ms. {1} had arrived at {2,ftime='%I o''clock'} at home. The exact time is {2,time=full}"
Синтаксис описывается следующей грамматикой:
format : '{' parameters '}'
parameters: parameter | parameter ',' parameters;
parameter : key ["=" value] ;
key : [0-9a-zA-Z<>]+ ;
value : ascii-string-excluding-"}"-and="," | local-string ;
local-string : quoted-text | quoted-text local-string;
quoted-text : '[^']*' ;
Вы можете включить буквальные «{» и «}», вставив в текст двойное «{{» или «}}».
cout <<
format(
translate(
"Unexpected `{{' in line {1} in file {2}")) % pos % file;
Показать что-то вроде
Unexpected `{' in line 5 in file source.cpp
Поддерживаются следующие пары ключевых значений формата:
[0-9]+– цифры, индекс отформатированного параметра – требуется.
numилиnumber– форматировать число. Варианты:
hex– отображение в шестнадцатеричном формате
oct– дисплей в октальном формате
sciилиscientific– отображение в научном формате
fixилиfixed– дисплей в фиксированном формате
Например,number=sci
curилиcurrency– формат валюты. Варианты:
iso– отображение с использованием символа валюты ISO.
natилиnational– отображение с использованием символа национальной валюты.
perилиpercent– форматировать процентное значение.
date,time,datetimeилиdt– форматировать дату, время или дату и время. Варианты:
sилиshort– дисплей в коротком формате.
mилиmedium– дисплей в среднем формате.
lилиlong– дисплей в длинном формате.
fилиfull– отображение в полном формате.
ftimeс струнным (цитируемым) параметром – отображение какstrftime.as::ftimeМанипулятор.
spellилиspellout– запишите число.
ordилиordinal– форматировать порядковое число (1-е, 2-е... и т.д.)
leftили<– выравнивание влево.
rightили>[>] [>].
widthилиw– ширина заданного поля (требуется параметр).
precisionилиp– заданная точность (требуется параметр).
locale– с параметром – переключайте локальные параметры для текущей работы. Эта команда генерирует локализацию с гранями форматирования, давая более тонкий зернистый контроль форматирования. Например:
cout<<
формат"Эта статья была опубликована по адресу {1,date=l} (грегорианский) {1,locale=he_IL@calendar=hebrew,date=l}] %
дата;
[ORIG_END] -->
timezoneилиtz– название часового пояса для отображения времени. Например:
cout<<
формат"Время: Местное {1,time}, ({1,time,tz=EET} Восточноевропейское время)"] %
дата;
[ORIG_END] -->
local- отображение времени в местном времени
gmt- отображение времени в временной шкале UTCcout<<
формат"Местное время: {1, время, местное}, универсальное время {1, время, гмт}"] %
время;
[ORIG_END] -->
Конструктор для классаформатаможет принимать сообщение типасообщения, упрощая интеграцию с кодом перевода сообщения.
Например:
cout<<
format(
translate(
"Adding {1} to {2}, we get {3}")) % a % b % (a+b) << endl;
Форматированная строка может быть получена непосредственно с помощьюstr(std::locale const &loc=std::locale())Функция члена. Например:
std::wstring de = (
wformat(
translate(
"Adding {1} to {2}, we get {3}")) % a % b % (a+b)).str(de_locale);
std::wstring fr = (
wformat(
translate(
"Adding {1} to {2}, we get {3}")) % a % b % (a+b)).str(fr_locale);
- Note
- There is one significant difference between
boost::format and boost::locale::format: Boost.Locale's format converts its parameters only when written to an ostream or when the str() member function is called. It only saves references to the objects that can be written to a stream.
Как правило, это не проблема, когда все операции выполняются в одном заявлении, например:
cout <<
format(
"Adding {1} to {2}, we get {3}") % a % b % (a+b);
Потому что временное значение<>(a+b) существует до тех пор, пока отформатированные данные фактически не будут записаны в поток. Но следующий код ошибочен:
format fmt(
"Adding {1} to {2}, we get {3}");
fmt % a;
fmt % b;
fmt % (a+b);
cout << fmt;
Потому что временное значение<>(a+b) больше не существует, когда<fmt>записано в поток. Правильным решением было бы:
format fmt(
"Adding {1} to {2}, we get {3}");
fmt % a;
fmt % b;
int a_plus_b = a+b;
fmt % a_plus_b;
cout << fmt;