Манипуляторы<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;