format.html 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059
  1. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
  2. <html>
  3. <head>
  4. <meta http-equiv="Content-Language" content="en-us">
  5. <meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
  6. <title>The Boost Format library</title>
  7. </head>
  8. <body bgcolor="white" text="black">
  9. <h1><img align="middle" alt="boost.png (6897 bytes)" height="86" src=
  10. "../../../boost.png" width="277">The Boost Format library</h1>
  11. <p>The <code><a href=
  12. "../../../boost/format.hpp">&lt;boost/format.hpp&gt;</a></code> format
  13. class provides printf-like formatting, in a type-safe manner which allows
  14. output of user-defined types.<br></p>
  15. <ul>
  16. <li><a href="#synopsis">Synopsis</a></li>
  17. <li><a href="#how_it_works">How it works</a></li>
  18. <li><a href="#examples">Examples</a></li>
  19. <li>
  20. <a href="#syntax">Syntax</a>
  21. <ul>
  22. <li><a href="#printf_directives">printf format-specification
  23. syntax</a></li>
  24. <li><a href="#printf_differences">Incompatibilities with
  25. printf</a></li>
  26. </ul>
  27. </li>
  28. <li><a href="#manipulators">Manipulators and the internal stream
  29. state</a></li>
  30. <li><a href="#user-defined">User-defined types</a></li>
  31. <li><a href="#alternatives">Alternatives</a></li>
  32. <li><a href="#exceptions">Exceptions</a></li>
  33. <li><a href="#performance">Performance</a></li>
  34. <li><a href="#extract">Class Interface Extract</a></li>
  35. <li><a href="#rationale">Rationale</a></li>
  36. </ul><a name="synopsis" id="synopsis"></a>
  37. <hr>
  38. <h2>Synopsis</h2>
  39. <p>A format object is constructed from a format-string, and is then given
  40. arguments through repeated calls to <i>operator%</i>.<br>
  41. Each of those arguments are then converted to strings, who are in turn
  42. combined into one string, according to the format-string.</p>
  43. <blockquote>
  44. <pre>
  45. cout &lt;&lt; boost::format("writing %1%, x=%2% : %3%-th try") % "toto" % 40.23 % 50;
  46. // prints "writing toto, x=40.230 : 50-th try"
  47. </pre>
  48. </blockquote><a name="how_it_works" id="how_it_works"></a>
  49. <hr>
  50. <h2>How it works</h2>
  51. <ol>
  52. <li>When you call <i>format(s)</i>, where s is the format-string, it
  53. constructs an object, which parses the format string and look for all
  54. directives in it and prepares internal structures for the next step.</li>
  55. <li>Then, either immediately, as in
  56. <blockquote>
  57. <pre>
  58. cout &lt;&lt; format("%2% %1%") % 36 % 77;
  59. </pre>
  60. </blockquote>or later on, as in
  61. <blockquote>
  62. <pre>
  63. format fmter("%2% %1%");
  64. fmter % 36; fmter % 77;
  65. </pre>
  66. </blockquote>you <i>feed</i> variables into the formatter.<br>
  67. those variables are dumped into an internal stream, which state is set
  68. according to the given formatting options in the format-string -if
  69. there are any-, and the format object stores the string results for the
  70. last step.
  71. </li>
  72. <li>Once all arguments have been fed you can dump the format object to a
  73. stream, or get its string value by using the <i>str()</i> member
  74. function, or the free function <i>str(const format&amp; )</i> in
  75. namespace <i>boost</i>. The result string stays accessible in the format
  76. object until another argument is passed, at which time it is
  77. reinitialised.
  78. <blockquote>
  79. <pre>
  80. // fmter was previously created and fed arguments, it can print the result :
  81. cout &lt;&lt; fmter ;
  82. // You can take the string result :
  83. string s = fmter.str();
  84. // possibly several times :
  85. s = fmter.str( );
  86. // You can also do all steps at once :
  87. cout &lt;&lt; boost::format("%2% %1%") % 36 % 77;
  88. // using the str free function :
  89. string s2 = str( format("%2% %1%") % 36 % 77 );
  90. </pre>
  91. </blockquote>
  92. </li>
  93. <li>Optionnally, after step 3, you can re-use a format object and restart
  94. at step2 : <i>fmter % 18 % 39;</i><br>
  95. to format new variables with the same format-string, saving the expensive
  96. processing involved at step 1.</li>
  97. </ol>All in all, the format class translates a format-string (with
  98. eventually printf-like directives) into operations on an internal stream,
  99. and finally returns the result of the formatting, as a string, or directly
  100. into an output stream. <a name="examples" id="examples"></a>
  101. <hr>
  102. <h2>Examples</h2>
  103. <blockquote>
  104. <pre>
  105. using namespace std;
  106. using boost::format;
  107. using boost::io::group;
  108. </pre>
  109. </blockquote>
  110. <ul>
  111. <li>Simple output, with reordering :
  112. <blockquote>
  113. <pre>
  114. cout &lt;&lt; format("%1% %2% %3% %2% %1% \n") % "11" % "22" % "333"; // 'simple' style.
  115. </pre>
  116. </blockquote>It prints : "11 22 333 22 11 \n"
  117. </li>
  118. <li>More precise formatting, with Posix-printf positional directives :
  119. <blockquote>
  120. <pre>
  121. cout &lt;&lt; format("(x,y) = (%1$+5d,%2$+5d) \n") % -23 % 35; // Posix-Printf style
  122. </pre>
  123. </blockquote>It prints : "(x,y) = ( -23, +35) \n"
  124. </li>
  125. <li>classical printf directive, no reordering :
  126. <blockquote>
  127. <pre>
  128. cout &lt;&lt; format("writing %s, x=%s : %d-th step \n") % "toto" % 40.23 % 50;
  129. </pre>
  130. </blockquote>It prints : "writing toto, x=40.23 : 50-th step \n"
  131. </li>
  132. <li>Several ways to express the same thing :
  133. <blockquote>
  134. <pre>
  135. cout &lt;&lt; format("(x,y) = (%+5d,%+5d) \n") % -23 % 35;
  136. cout &lt;&lt; format("(x,y) = (%|+5|,%|+5|) \n") % -23 % 35;
  137. cout &lt;&lt; format("(x,y) = (%1$+5d,%2$+5d) \n") % -23 % 35;
  138. cout &lt;&lt; format("(x,y) = (%|1$+5|,%|2$+5|) \n") % -23 % 35;
  139. </pre>
  140. </blockquote>all those print : "(x,y) = ( -23, +35) \n"
  141. </li>
  142. <li>Using manipulators to modify the format-string :
  143. <blockquote>
  144. <pre>
  145. format fmter("_%1$+5d_ %1$d \n");
  146. format fmter2("_%1%_ %1% \n");
  147. fmter2.modify_item(1, group(showpos, setw(5)) );
  148. cout &lt;&lt; fmter % 101 ;
  149. cout &lt;&lt; fmter2 % 101 ;
  150. </pre>
  151. </blockquote>Both print the same : "_ +101_ 101 \n"
  152. </li>
  153. <li>Using manipulators with arguments :
  154. <blockquote>
  155. <pre>
  156. cout &lt;&lt; format("_%1%_ %1% \n") % group(showpos, setw(5), 101);
  157. </pre>
  158. </blockquote>The manipulators are applied at each occurrence of %1%, and
  159. thus it prints : "_ +101_ +101 \n"
  160. </li>
  161. <li>New formatting feature : 'absolute tabulations', useful inside loops,
  162. to insure a field is printed at the same position from one line to the
  163. next, even if the widthes of the previous arguments can vary a lot.
  164. <blockquote>
  165. <pre>
  166. for(unsigned int i=0; i &lt; names.size(); ++i)
  167. cout &lt;&lt; format("%1%, %2%, %|40t|%3%\n") % names[i] % surname[i] % tel[i];
  168. </pre>
  169. </blockquote>For some std::vector <i>names</i>, <i>surnames</i>, and
  170. <i>tel</i> (see sample_new_features.cpp) it prints :
  171. <blockquote>
  172. <pre>
  173. Marc-Fran&ccedil;ois Michel, Durand, +33 (0) 123 456 789
  174. Jean, de Lattre de Tassigny, +33 (0) 987 654 321
  175. </pre>
  176. </blockquote>
  177. </li>
  178. </ul>
  179. <hr>
  180. <h2>Sample Files</h2>
  181. <p>The program <a href=
  182. "../example/sample_formats.cpp">sample_formats.cpp</a> demonstrates simple
  183. uses of <b>format</b>.<br></p>
  184. <p><a href="../example/sample_new_features.cpp">sample_new_features.cpp</a>
  185. illustrates the few formatting features that were added to printf's syntax
  186. such as simple positional directives, centered alignment, and
  187. 'tabulations'.<br></p>
  188. <p><a href="../example/sample_advanced.cpp">sample_advanced.cpp</a>
  189. demonstrates uses of advanced features, like reusing, and modifying, format
  190. objects, etc..<br></p>
  191. <p>And <a href="../example/sample_userType.cpp">sample_userType.cpp</a>
  192. shows the behaviour of the <b>format</b> library on user-defined
  193. types.</p><a name="syntax" id="syntax"></a>
  194. <hr>
  195. <h2>Syntax</h2>
  196. <p><b>boost::format(</b> format-string <b>) %</b> arg1 <b>%</b> arg2
  197. <b>%</b> ... <b>%</b> argN</p>
  198. <p>The <i>format-string</i> contains text in which special directives will
  199. be replaced by strings resulting from the formatting of the given
  200. arguments.<br>
  201. The legacy syntax in the C and C++ worlds is the one used by printf, and
  202. thus format can use directly printf format-strings, and produce the same
  203. result (in almost all cases. see <a href=
  204. "#printf_differences">Incompatibilities with printf</a> for details)<br>
  205. This core syntax was extended, to allow new features, but also to adapt to
  206. the C++ streams context. Thus, format accepts several forms of directives
  207. in format-strings :</p>
  208. <ul>
  209. <li>Legacy printf format strings : <b>%</b><i>spec</i> where <i>spec</i>
  210. is a <a href="#printf_directives">printf format specification</a><br>
  211. <i>spec</i> passes formatting options, like width, alignment, numerical
  212. base used for formatting numbers, as well as other specific flags. But
  213. the classical <i>type-specification</i> flag of printf has a weaker
  214. meaning in format. It merely sets the appropriate flags on the internal
  215. stream, and/or formatting parameters, but does not require the
  216. corresponding argument to be of a specific type.<br>
  217. e.g. : the specification <i>2$x</i>, meaning "print argument number 2,
  218. which is an integral number, in hexa" for printf, merely means "print
  219. argument 2 with stream basefield flags set to <i>hex</i>" for
  220. format.</li>
  221. <li><b>%|</b><i>spec</i><b>|</b> where <i>spec</i> is a printf format
  222. specification.<br>
  223. This pipe-delimited syntax is introduced, to improve the readability of the
  224. format-string, but primarily, to make the <i>type-conversion
  225. character</i> optional in <i>spec</i>. This information is not necessary
  226. with C++ variables, but with direct printf syntax, it is necessary to
  227. always give a type-conversion character, merely because this character is
  228. crucial to determine the end of a format-specification.<br>
  229. e.g. : "%|-5|" will format the next variable with width set to 5, and
  230. left-alignment just like the following printf directives : "%-5g",
  231. "%-5f", "%-5s" ..</li>
  232. <li><b>%</b><i>N</i><b>%</b><br>
  233. This simple positional notation requests the formatting of the
  234. <i>N</i>-th argument - wihout any formatting option.<br>
  235. (It's merely a shortcut to Printf's positional directives (like
  236. "%<i>N</i>$s"), but a major benefit is that it's much more readable, and
  237. does not use a "type-conversion" character)</li>
  238. </ul>On top of the standard printf format specifications, new features were
  239. implemented, like centered alignment. See <a href="#new_directives">new
  240. format specification</a> for details. <a name="printf_directives" id=
  241. "printf_directives"></a>
  242. <h3>printf format specifications</h3>
  243. <p>The printf format specifications supported by Boost.format follows the
  244. Unix98 <a href=
  245. "http://www.opengroup.org/onlinepubs/7908799/xsh/fprintf.html">Open-group
  246. printf</a> precise syntax, rather than the standard C printf, which does
  247. not support positional arguments. (Common flags have the same meaning in
  248. both, so it should not be a headache for anybody)<br>
  249. <i>Note that it is an error to use positional format specifications</i>
  250. (e.g. <i>%3$+d</i>) <i>mixed with non-positional ones</i> (e.g. <i>%+d</i>)
  251. <i>in the same format string.</i><br>
  252. In the Open-group specification, referring to the same argument several
  253. times (e.g. <i>"%1$d %1$d"</i>) has undefined behaviour. Boost.format's
  254. behaviour in such cases is to allow each argument to be reffered to any
  255. number of times. The only constraint is that it expects exactly <i>P</i>
  256. arguments, <i>P</i> being the maximum argument number used in the format
  257. string. (e.g., for "%1$d %10$d", <i>P</i> == 10 ).<br>
  258. Supplying more, or less, than <i>P</i> arguments raises an exception.
  259. (unless it was set otherwise, see <a href="#exceptions">exceptions</a>)</p>
  260. <p>A specification <i>spec</i> has the form:
  261. <pre> [ <i>N</i><b>$</b> ] [ <i>flags</i> ] [ <i>width</i> ] [ <b>.</b> <i>precision</i> ] [ <i>argument-type</i> ] <i>conversion-specifier</i></pre>
  262. Fields inside square brackets are optional. Each of those fields are
  263. explained one by one in the following list:</p>
  264. <ul>
  265. <li><i>N</i> <b>$</b> (optional field) specifies that the format
  266. specification applies to the <i>N</i>-th argument (it is called a
  267. <i>positional format specification</i>).<br>
  268. If this is not present, arguments are taken one by one. (and it is then
  269. an error to later supply an argument number)</li><br />
  270. <li>
  271. <i>flags</i> is a sequence of any of these:
  272. <blockquote>
  273. <table border="1" cellpadding="5" summary="">
  274. <tr>
  275. <td><b>Flag</b></td>
  276. <td><b>Meaning</b></td>
  277. <td><b>effect on internal stream</b></td>
  278. </tr>
  279. <tr>
  280. <td><b>'-'</b></td>
  281. <td>left alignment</td>
  282. <td>N/A (applied later on the string)</td>
  283. </tr>
  284. <tr>
  285. <td><b>'='</b></td>
  286. <td>centered alignment</td>
  287. <td>N/A (applied later on the string)<br>
  288. <i>- note : added feature, not in printf -</i></td>
  289. </tr>
  290. <tr>
  291. <td><b>'_'</b></td>
  292. <td>internal alignment</td>
  293. <td>sets internal alignment<br>
  294. <i>- note : added feature, not in printf -</i></td>
  295. </tr>
  296. <tr>
  297. <td><b>'+'</b></td>
  298. <td>show sign even for positive numbers</td>
  299. <td>sets <i>showpos</i></td>
  300. </tr>
  301. <tr>
  302. <td><b>'#'</b></td>
  303. <td>show numerical base, and decimal point</td>
  304. <td>sets <i>showbase</i> and <i>showpoint</i></td>
  305. </tr>
  306. <tr>
  307. <td><b>'0'</b></td>
  308. <td>pad with 0's (inserted after sign or base indicator)</td>
  309. <td>if not left-aligned, calls <i>setfill('0')</i> and sets
  310. <i>internal</i><br>
  311. Extra actions are taken after stream conversion to handle
  312. <a href="#user-defined">user-defined output</a>.</td>
  313. </tr>
  314. <tr>
  315. <td><b>' '</b></td>
  316. <td>if the string does not begin with <i>+</i> or <i>-</i>,
  317. insert a <i>space</i> before the converted string</td>
  318. <td>N/A (applied later on the string)<br>
  319. Different to printf's behaviour : it is not affected by internal
  320. alignment</td>
  321. </tr>
  322. </table>
  323. </blockquote><br />
  324. </li>
  325. <li><i>width</i> specifies a minimal width for the string resulting form
  326. the conversion. If necessary, the string will be padded with alignment
  327. and fill characters either set on the stream via manipulators, or
  328. specified by the format-string (e.g. flags '0', '-', ..)<br>
  329. Note that width is not just set on the conversion stream. To support
  330. output of <a href="#user-defined">user-defined types</a> (that might call
  331. <i>operator&lt;&lt;</i> many times on several members), the width is
  332. handled after stream conversion of the whole argument object, in the
  333. format class code.</li><br />
  334. <li>
  335. <i>precision</i> (preceded by a point), sets the stream's
  336. <i>precision</i>
  337. <ul>
  338. <li>When outputting a floatting type number, it sets the maximum
  339. number of digits
  340. <ul>
  341. <li>after decimal point when in fixed or scientific mode</li>
  342. <li>in total when in default mode ('<i>general mode</i>', like
  343. <i>%g</i>)</li>
  344. </ul>
  345. </li>
  346. <li>When used with type-char <b>s</b> or <b>S</b> it takes another
  347. meaning : the conversion string is truncated to the <i>precision</i>
  348. first chars. (Note that the eventual padding to <i>width</i> is done
  349. after truncation.)</li>
  350. </ul><br />
  351. </li>
  352. <li>
  353. <i>argument-type</i> is used by the printf family to properly process
  354. the arguments being passed in through varargs. With <code>boost::format</code>
  355. the arguments are fed into format through <code>operator %</code> which
  356. allows the template to carry the argument type. Therefore the classical
  357. printf style argument type is consumed and ignored.
  358. Argument-types <code>hh</code>, <code>h</code>, <code>l</code>, <code>ll</code>, <code>j</code>,
  359. <code>z</code>, and <code>L</code> are recognized, as are the Microsoft extensions <code>w</code>,
  360. <code>I</code> (capital i), <code>I32</code>, and <code>I64</code>. Argument-type <code>t</code>
  361. from the ISO C99 standard is not recognized as an argument type, as it has been in use as a
  362. conversion specifier for tabular output for many years in <code>boost::format</code>.
  363. </li><br />
  364. <li>
  365. <i>conversion-specifier</i> does <b>not</b> impose the concerned argument
  366. to be of a restricted set of types, but merely sets the ios flags that are
  367. associated with a type specification:
  368. <blockquote>
  369. <table border="1" cellpadding="5" summary="">
  370. <tr>
  371. <td><b>conversion-specifier</b></td>
  372. <td><b>Meaning</b></td>
  373. <td><b>effect on stream</b></td>
  374. </tr>
  375. <tr>
  376. <td><b>b</b></td>
  377. <td>boolean string output</td>
  378. <td>sets <i>boolalpha</i>; only works for type <code>bool</code><br />
  379. To customize the resulting string, see
  380. <a href="http://en.cppreference.com/w/cpp/locale/numpunct/truefalsename">std::numpunct</a>.
  381. </tr>
  382. <tr>
  383. <td><b>p or x</b></td>
  384. <td>hexadecimal output</td>
  385. <td>sets <i>hex</i></td>
  386. </tr>
  387. <tr>
  388. <td><b>o</b></td>
  389. <td>octal output</td>
  390. <td>sets <i>oct</i></td>
  391. </tr>
  392. <tr>
  393. <td><b>a</b></td>
  394. <td>hexadecimal exponent notation</td>
  395. <td>sets floatfield bits to <i>scientific</i> | <i>fixed</i> (which is equivalent to <i>hexfloat</i>)</td>
  396. </tr>
  397. <tr>
  398. <td><b>e</b></td>
  399. <td>scientific float format</td>
  400. <td>sets floatfield bits to <i>scientific</i></td>
  401. </tr>
  402. <tr>
  403. <td><b>f</b></td>
  404. <td>fixed float format</td>
  405. <td>sets floatfield bits to <i>fixed</i></td>
  406. </tr>
  407. <tr>
  408. <td><b>g</b></td>
  409. <td>general -default- float format</td>
  410. <td><b>unset</b> all floatfield bits</td>
  411. </tr>
  412. <tr>
  413. <td><b>X, A, E, F</b> or <b>G</b></td>
  414. <td>same effect as their lowercase counterparts, but using
  415. uppercase letters for number outputs. (exponents, hex digits,
  416. ..)</td>
  417. <td>same effects as <i>'x'</i>, <i>'a'</i>, <i>'e'</i>, <i>'f'</i>, or <i>'g'</i> respectively,
  418. <b>plus</b> <i>uppercase</i></td>
  419. </tr>
  420. <tr>
  421. <td><b>d, i</b> or <b>u</b></td>
  422. <td><b>decimal</b> type output</td>
  423. <td>sets basefield bits to <i>dec</i></td>
  424. </tr>
  425. <tr>
  426. <td><b>s</b> or <b>S</b></td>
  427. <td>string output</td>
  428. <td><i>precision</i> specification is unset, and its value goes
  429. to an internal field for later 'truncation'. (see
  430. <i>precision</i> explanation above)</td>
  431. </tr>
  432. <tr>
  433. <td><b>c</b> or <b>C</b></td>
  434. <td>1-character output</td>
  435. <td>only the first character of the conversion string is
  436. used.</td>
  437. </tr>
  438. <tr>
  439. <td><b>%</b></td>
  440. <td>print the character <i>%</i></td>
  441. <td>N/A</td>
  442. </tr>
  443. </table>
  444. </blockquote>
  445. <p>Note that the 'n' conversion-specifier is ignored (and so is the
  446. corresponding argument), because it does not fit in this context.</p>
  447. </li>
  448. </ul><a name="new_directives" id="new_directives"></a>
  449. <h3>new format-specifications</h3>
  450. <ul>
  451. <li>as stated in the flags table, centered and internal alignment flags
  452. (' <i>=</i> ', and ' <i>_</i> ') were added.</li>
  453. <li><i><b>%{</b>n</i><b>t}</b> , where <i>n</i> is a positive number,
  454. inserts an <i>absolute tabulation</i>. It means that format will, if
  455. needed, fill the string with characters, until the length of the string
  456. created so far reaches <i>n</i> characters. (see <a href=
  457. "#examples">examples</a> )</li>
  458. <li><b>%|</b><i>n</i><b>T</b><i>X</i><b>|</b> inserts a tabulation in the
  459. same way, but using <i>X</i> as fill character instead of the current
  460. 'fill' char of the stream (which is <i>space</i> for a stream in default
  461. state)</li>
  462. </ul><a name="printf_differences" id="printf_differences"></a>
  463. <h2>Differences of behaviour vs printf</h2>Suppose you have variables
  464. <i>x1, x2</i> (built_in types, supported by C's printf),<br>
  465. and a format string <i>s</i> intended for use with a printf function this
  466. way :
  467. <blockquote>
  468. <pre>
  469. printf(s, x1, x2);
  470. </pre>
  471. </blockquote><br>
  472. In almost all cases, the result will be the same as with this command :
  473. <blockquote>
  474. <pre>
  475. cout &lt;&lt; format(s) % x1 % x2;
  476. </pre>
  477. </blockquote>
  478. <p>But because some printf format specifications don't translate well into
  479. stream formatting options, there are a few notable imperfections in the way
  480. Boost.format emulates printf.<br>
  481. In any case, the <i>format</i> class should quietly ignore the unsupported
  482. options, so that printf format-strings are always accepted by format and
  483. produce almost the same output as printf.</p><br>
  484. Here is the full list of such differences :
  485. <ul>
  486. <li><b>'0'</b> and <b>' '</b> options : printf ignores these options for
  487. non numeric conversions, but format applies them to all types of
  488. variables. (so it is possible to use those options on user-defined types,
  489. e.g. a Rational class, etc..)</li>
  490. <li><b>precision</b> for integral types arguments has a special meaning
  491. for printf :<br>
  492. <i>printf( "(%5.3d)" , 7 ) ;</i> prints &laquo; ( 007) &raquo;<br>
  493. While format, like streams, ignores the precision parameter for integral
  494. types conversions.</li>
  495. <li>the <b>'</b> printf option (<i>format with thousands grouping
  496. characters)</i>) has no effect in format.</li>
  497. <li>Width or precision set to asterisk (<i>*</i>) are used by printf to
  498. read this field from an argument. e.g.
  499. <i>printf("%1$d:%2$.*3$d:%4$.*3$d\n", hour, min, precision, sec);</i><br>
  500. This class does not support this mechanism for now. so such precision or
  501. width fields are quietly ignored by the parsing.</li>
  502. <li>argument-type is ignored</li>
  503. </ul>Also, note that the special <b>'n'</b> type-specification (used to
  504. tell printf to save in a variable the number of characters output by the
  505. formatting) has no effect in format.<br>
  506. Thus format strings containing this type-specification should produce the
  507. same converted string by printf or format. It will not cause differences in
  508. the formatted strings between printf and format.<br>
  509. To get the number of characters in the formatted string using Boost.Format,
  510. you can use the <i>size()</i> member function :
  511. <blockquote>
  512. <pre>
  513. format formatter("%+5d");
  514. cout &lt;&lt; formatter % x;
  515. unsigned int n = formatter.size();
  516. </pre>
  517. </blockquote><a name="user-defined" id="user-defined"></a>
  518. <hr>
  519. <h2>User-defined types output</h2>
  520. <p>All flags which are translated into modification to the stream state act
  521. recursively within user-defined types. ( the flags remain active, and so
  522. does the desired format option, for each of the '&lt;&lt;' operations that
  523. might be called by the user-defined class)</p>e.g., with a Rational class,
  524. we would have something like :
  525. <blockquote>
  526. <pre>
  527. Rational ratio(16,9);
  528. cerr &lt;&lt; format("%#x \n") % ratio; // -&gt; "0x10/0x9 \n"
  529. </pre>
  530. </blockquote>
  531. <p>It's a different story for other formatting options. For example,
  532. setting width applies to the final output produced by the object, not to
  533. each of its internal outputs, and that's fortunate :</p>
  534. <blockquote>
  535. <pre>
  536. cerr &lt;&lt; format("%-8d") % ratio; // -&gt; "16/9 " and not "16 /9 "
  537. cerr &lt;&lt; format("%=8d") % ratio; // -&gt; " 16/9 " and not " 16 / 9 "
  538. </pre>
  539. </blockquote>
  540. <p><br>
  541. But so does the 0 and ' ' options (contrarily to '+' which is directly
  542. translated to the stream state by <i>showpos</i>. But no such flags exist
  543. for the zero and space printf options)<br>
  544. and that is less natural :</p>
  545. <blockquote>
  546. <pre>
  547. cerr &lt;&lt; format("%+08d \n") % ratio; // -&gt; "+00016/9"
  548. cerr &lt;&lt; format("% 08d \n") % ratio; // -&gt; "000 16/9"
  549. </pre>
  550. </blockquote>It is possible to obtain a better behaviour by carefully
  551. designing the Rational's <i>operator&lt;&lt;</i> to handle the stream's
  552. width, alignment and <i>showpos</i> paramaters by itself. This is
  553. demonstrated in <a href=
  554. "../example/sample_userType.cpp">sample_userType.cpp</a>. <a name=
  555. "manipulators" id="manipulators"></a>
  556. <hr>
  557. <h3>Manipulators, and internal stream state</h3>
  558. <p>The internal stream state of <b>format</b> is saved before and restored
  559. after output of an argument; therefore, the modifiers are not sticky and
  560. affect only the argument they are applied to.<br>
  561. The default state for streams, as stated by the standard, is : precision 6,
  562. width 0, right alignment, and decimal flag set.</p>
  563. <p>The state of the internal <b>format</b> stream can be changed by
  564. manipulators passed along with the argument; via the <i>group</i> function,
  565. like that :</p>
  566. <blockquote>
  567. <pre>
  568. cout &lt;&lt; format("%1% %2% %1%\n") % group(hex, showbase, 40) % 50; // prints "0x28 50 0x28\n"
  569. </pre>
  570. </blockquote>
  571. <p><br>
  572. When passing N items inside a 'group' Boost.format needs to process
  573. manipulators diferently from regular argument, and thus using group is
  574. subject to the following constraints :</p>
  575. <ol>
  576. <li>the object to be printed must be passed as the last item in the
  577. group</li>
  578. <li>the first N-1 items are treated as manipulators, and if they do
  579. produce output, it is discarded</li>
  580. </ol>
  581. <p>Such manipulators are passed to the streams right before the following
  582. argument, at every occurrence. Note that formatting options specified within
  583. the format string are overridden by stream state modifiers passed this way.
  584. For instance in the following code, the <i>hex</i> manipulator has priority
  585. over the <i>d</i> type-specification in the format-string which would set
  586. decimal output :</p>
  587. <blockquote>
  588. <pre>
  589. cout &lt;&lt; format("%1$d %2% %1%\n") % group(hex, showbase, 40) % 50;
  590. // prints "0x28 50 0x28\n"
  591. </pre>
  592. </blockquote><a name="alternatives" id="alternatives"></a>
  593. <h2>Alternatives</h2>
  594. <ul>
  595. <li><b>printf</b> is the classical alternative, that is not type safe and
  596. not extendable to user-defined types.</li>
  597. <li>ofrstream.cc by Karl Nelson's design was a big source of inspiration
  598. to this format class.</li>
  599. <li>James Kanze's library has a format class (in
  600. <i>srcode/Extended/format</i> ) which looks very well polished. Its
  601. design has in common with this class the use of internal stream for the
  602. actual conversions, as well as using operators to pass arguments. (but
  603. his class, as ofrstream, uses <i>operator&lt;&lt;</i> rather <i>than
  604. operator%</i> )</li>
  605. <li><a href="http://groups.yahoo.com/group/boost/files/format3/">Karl
  606. Nelson's library</a> was intented as demonstration of alternative
  607. solutions in discussions on Boost's list for the design of
  608. Boost.format.</li>
  609. <li><a href="http://fmtlib.net/latest/index.html">{fmt}</a> by Victor Zverovich.</li>
  610. </ul><a name="exceptions" id="exceptions"></a>
  611. <hr>
  612. <h2>Exceptions</h2>
  613. <p>Boost.format enforces a number of rules on the usage of format objects.
  614. The format-string must obeys the syntax described above, the user must
  615. supply exactly the right number of arguments before outputting to the final
  616. destination, and if using modify_item or bind_arg, items and arguments
  617. index must not be out of range.<br>
  618. When format detects that one of these rules is not satisfied, it raises a
  619. corresponding exception, so that the mistakes don't go unnoticed and
  620. unhandled.<br>
  621. But the user can change this behaviour to fit his needs, and select which
  622. types of errors may raise exceptions using the following functions :</p>
  623. <blockquote>
  624. <pre>
  625. unsigned char exceptions(unsigned char newexcept); // query and set
  626. unsigned char exceptions() const; // just query
  627. </pre>
  628. </blockquote>
  629. <p>The user can compute the argument <i>newexcept</i> by combining the
  630. following atoms using binary arithmetic :</p>
  631. <ul>
  632. <li><b>boost::io::bad_format_string_bit</b> selects errors due to
  633. ill-formed format-strings.</li>
  634. <li><b>boost::io::too_few_args_bit</b> selects errors due to asking for
  635. the srting result before all arguments are passed.</li>
  636. <li><b>boost::io::too_many_args_bit</b> selects errors due to passing too
  637. many arguments.</li>
  638. <li><b>boost::io::out_of_range_bit</b> select errors due to out of range
  639. index supplied by the user when calling <i>modify_item</i> or other
  640. functions taking an item index (or an argument index)</li>
  641. <li><b>boost::io::all_error_bits</b> selects all errors</li>
  642. <li><b>boost::io::no_error_bits</b> selects no error.</li>
  643. </ul>
  644. <p>For instance, if you don't want Boost.format to detect bad number of
  645. arguments, you can define a specific wrapper function for building format
  646. objects with the right exceptions settings :</p>
  647. <blockquote>
  648. <pre>
  649. boost::format my_fmt(const std::string &amp; f_string) {
  650. using namespace boost::io;
  651. format fmter(f_string);
  652. fmter.exceptions( all_error_bits ^ ( too_many_args_bit | too_few_args_bit ) );
  653. return fmter;
  654. }
  655. </pre>
  656. </blockquote>It is then allowed to give more arguments than needed (they
  657. are simply ignored) :
  658. <blockquote>
  659. <pre>
  660. cout &lt;&lt; my_fmt(" %1% %2% \n") % 1 % 2 % 3 % 4 % 5;
  661. </pre>
  662. </blockquote>And if we ask for the result before all arguments are
  663. supplied, the corresponding part of the result is simply empty
  664. <blockquote>
  665. <pre>
  666. cout &lt;&lt; my_fmt(" _%2%_ _%1%_ \n") % 1 ;
  667. // prints " __ _1_ \n"
  668. </pre>
  669. </blockquote><a name="performance" id="performance"></a>
  670. <hr>
  671. <h2>A Note about performance</h2>
  672. <p>The performance of boost::format for formatting a few builtin type
  673. arguments with reordering can be compared to that of Posix-printf, and of
  674. the equivalent stream manual operations to give a measure of the overhead
  675. incurred. The result may greatly depend on the compiler, standard library
  676. implementation, and the precise choice of format-string and arguments.</p>
  677. <p>Common stream implementations eventually call functions of the
  678. printf family for the actual formatting of numbers. In general, printf
  679. will be noticeably faster than the direct stream operations due to the
  680. reordering overhead (allocations to store the pieces of string, stream
  681. initialisation at each item formatting, ..). The direct stream operations
  682. would be faster than boost::format - one can expect a ratio ranging from 2
  683. to 5 or more.</p>
  684. <p>When iterated formattings are a performance bottleneck, performance can
  685. be slightly increased by parsing the format string into a format object,
  686. and copying it at each formatting, in the following way:</p>
  687. <blockquote>
  688. <pre>
  689. const boost::format fmter(fstring);
  690. dest &lt;&lt; boost::format(fmter) % arg1 % arg2 % arg3 ;
  691. </pre>
  692. </blockquote>
  693. <p>As an example of performance results, the author measured the time of
  694. execution of iterated formattings with 4 different methods:</p>
  695. <ol>
  696. <li>posix printf</li>
  697. <li>manual stream output (to a dummy <i>nullStream</i> stream sending the
  698. bytes into oblivion)</li>
  699. <li>boost::format copied from a const object as shown above</li>
  700. <li>the straight boost::format usage</li>
  701. </ol>
  702. <p>the test was compiled with g++-3.3.3 and the following timings were
  703. measured (in seconds, and ratios):</p>
  704. <blockquote>
  705. <pre>
  706. string fstring="%3$0#6x %1$20.10E %2$g %3$0+5d \n";
  707. double arg1=45.23;
  708. double arg2=12.34;
  709. int arg3=23;
  710. - release mode :
  711. printf : 2.13
  712. nullStream : 3.43, = 1.61033 * printf
  713. boost::format copied : 6.77, = 3.1784 * printf , = 1.97376 * nullStream
  714. boost::format straight :10.67, = 5.00939 * printf , = 3.11079 * nullStream
  715. - debug mode :
  716. printf : 2.12
  717. nullStream : 3.69, = 1.74057 * printf
  718. boost::format copied :10.02, = 4.72642 * printf , = 2.71545 * nullStream
  719. boost::format straight :17.03, = 8.03302 * printf , = 4.61518 * nullStream
  720. </pre>
  721. </blockquote><a name="extract" id="extract"></a>
  722. <hr>
  723. <h2>Class Interface Extract</h2>
  724. <blockquote>
  725. <pre>
  726. namespace boost {
  727. template&lt;class charT, class Traits=std::char_traits&lt;charT&gt; &gt;
  728. class basic_format
  729. {
  730. public:
  731. typedef std::basic_string&lt;charT, Traits&gt; string_type;
  732. typedef typename string_type::size_type size_type;
  733. basic_format(const charT* str);
  734. basic_format(const charT* str, const std::locale &amp; loc);
  735. basic_format(const string_type&amp; s);
  736. basic_format(const string_type&amp; s, const std::locale &amp; loc);
  737. basic_format&amp; operator= (const basic_format&amp; x);
  738. void clear(); // reset buffers
  739. basic_format&amp; parse(const string_type&amp;); // clears and parse a new format string
  740. string_type str() const;
  741. size_type size() const;
  742. // pass arguments through those operators :
  743. template&lt;class T&gt; basic_format&amp; operator%(T&amp; x);
  744. template&lt;class T&gt; basic_format&amp; operator%(const T&amp; x);
  745. // dump buffers to ostream :
  746. friend std::basic_ostream&lt;charT, Traits&gt;&amp;
  747. operator&lt;&lt; &lt;&gt; ( std::basic_ostream&lt;charT, Traits&gt;&amp; , basic_format&amp; );
  748. // Choosing which errors will throw exceptions :
  749. unsigned char exceptions() const;
  750. unsigned char exceptions(unsigned char newexcept);
  751. // ............ this is just an extract .......
  752. }; // basic_format
  753. typedef basic_format&lt;char &gt; format;
  754. typedef basic_format&lt;wchar_t &gt; wformat;
  755. // free function for ease of use :
  756. template&lt;class charT, class Traits&gt;
  757. std::basic_string&lt;charT,Traits&gt; str(const basic_format&lt;charT,Traits&gt;&amp; f) {
  758. return f.str();
  759. }
  760. } // namespace boost
  761. </pre>
  762. </blockquote>
  763. <hr>
  764. <a name="rationale" id="rationale"></a>
  765. <h2>Rationale</h2>
  766. <p>This class's goal is to bring a better, C++, type-safe and
  767. type-extendable <i>printf</i> equivalent to be used with
  768. streams.</p>Precisely, <b>format</b> was designed to provide the following
  769. features :
  770. <ul>
  771. <li>support positional arguments (required for internationalisation)</li>
  772. <li>accept an unlimited number of arguments.</li>
  773. <li>make formatting commands visually natural.</li>
  774. <li>support the use of manipulators to modify the display of an argument.
  775. in addition to the format-string syntax.</li>
  776. <li>accept any types of variables, by relying on streams for the actual
  777. conversion to string. This specifically concerns user-defined types, for
  778. which the formatting options effects should be intuitively natural.</li>
  779. <li>provide printf-compatibility, as much as it makes sense in a
  780. type-safe and type-extendable context.</li>
  781. </ul>
  782. <p>In the process of the design, many issues were faced, and some choices
  783. were made, that might not be intuitively right. But in each case they were
  784. taken for <a href="choices.html">some reasons</a>.</p>
  785. <hr>
  786. <h2>Credits</h2>
  787. <p>The author of Boost format is Samuel Krempp. &nbsp; He used ideas from
  788. R&uuml;diger Loos' format.hpp and Karl Nelson's formatting classes.</p>
  789. <hr>
  790. <p><a href="http://validator.w3.org/check?uri=referer"><img border="0" src=
  791. "../../../doc/images/valid-html401.png" alt="Valid HTML 4.01 Transitional"
  792. height="31" width="88"></a></p>
  793. <p>Revised
  794. <!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B, %Y" startspan -->23 October, 2017<!--webbot bot="Timestamp" endspan i-checksum="38510" --></p>
  795. <p><i>Copyright &copy; 2002 Samuel Krempp</i></p>
  796. <p><i>Distributed under the Boost Software License, Version 1.0. (See
  797. accompanying file <a href="../../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or
  798. copy at <a href=
  799. "http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</a>)</i></p>
  800. </body>
  801. </html>