    <rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:admin="http://webns.net/mvcb/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:content="http://purl.org/rss/1.0/modules/content/">
     <channel>
        <title>ACCU  :: A Text Formatting Class</title>
        <link>https://members.accu.org/index.php/articles/600</link>
        <description>Professionalism in Programming</description>
        <dc:language>en-us</dc:language> 
        <dc:creator>Administrator</dc:creator> 
        <admin:generatorAgent rdf:resource="http://www.xaraya.org" /> 
        <admin:errorReportsTo rdf:resource="mailto:webeditor@accu.org" />
       <sy:updatePeriod>hourly</sy:updatePeriod>
       <sy:updateFrequency>1</sy:updateFrequency>
       <docs>http://backend.userland.com/rss</docs>




<div class="xar-mod-head"><span class="xar-mod-title">Programming Topics + Overload Journal #6 - Mar 1995</span></div>

<table border="0" cellpadding="1" cellspacing="0">
    <tbody>
    <tr>
        <td valign="top">
            Browse in :
       </td>
       <td valign="top">

                                            <a href="https://members.accu.org/index.php/articles/">All</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c13/">Topics</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c65/">Programming</a>
<br />

                                            <a href="https://members.accu.org/index.php/articles/">All</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c76/">Journals</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c78/">Overload</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c177/">06</a>
<br />

                                            <a href="https://members.accu.org/index.php/articles/c65-177/">Any of these categories</a>

                    -                        <a href="https://members.accu.org/index.php/articles/c65+177/">All of these categories</a>
<br />
</td>
   </tr>
   </tbody>
</table>




<div class="xar-error">
   <p>
 <strong>Note:</strong> when you create a new publication type,
the articles module will automatically use the templates
<em>user-display-[publicationtype].xt</em>
and <em>user-summary-[publicationtype].xt</em>.
If those templates do not exist when you try to preview or display a new article,
you'll get this warning :-)  Please place your own templates in themes/<em>yourtheme</em>/modules/articles . The templates will get the extension .xt there. </p>
</div>
<div class="xar-norm xar-standard-box-padding">
   <h1><strong>Title:</strong>&nbsp;A Text Formatting Class</h1>
<p><strong>Author:</strong>&nbsp;</p>
<p>
<strong>Date:</strong> 27 March 1995 18:22:18 +01:00 or Mon, 27 March 1995 18:22:18 +01:00</p>
<p><strong>Summary:</strong>&nbsp;</p>
<p><strong>Body:</strong>&nbsp;<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e18" id=
"d0e18"></a>Introduction</h2>
</div>
<p>I note that the Draft C++ Standard will provide a Standard
Library which I presume will include the existing iostream classes.
I do not know whether additional text formatting classes have been
added but, just in case they have not, I have outlined the features
of a class I have developed from ostream and its related
classes.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e23" id="d0e23"></a>The class</h2>
</div>
<p>The class, which I have called Formatter, provides for a
formatting string to specify how a sequence of object values is to
be formatting as text. It is based on a similar facility which I
developed in Ada 83 and presented at the Ada UK 93 Conference. The
implementation in C++ is much simpler (~250 lines of C++) thanks to
the support already provided by the ostream class hierarchy.</p>
<p>The class interprets a formatting string based on the
conventions used by printf() in C, but applies them in a totally
type-safe way, as described below.</p>
<p>Whilst the class provides little functionality that is not
already supported by ostream it allows this functionality to be
much more concisely, conveniently and obviously utilised (tabulated
output is easy!). I know that most people, familiar with printf()
in C, hanker after a similarly powerful and concise formatting
notation for use in C++.</p>
<p>Well here it is!</p>
<p>The class has been compiled and used with CenterLine C++ on a
Sparc. It no doubt could be refined and I believe a comparable
class could be developed for reading formatted input.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e36" id="d0e36"></a>Features and
functionality of the class Formatter</h2>
</div>
<div class="itemizedlist">
<ul type="disc">
<li>
<p>Applies a formatting string, in the style used by C's printf(),
to a sequence of object values.</p>
</li>
<li>
<p>The formatting is completely type-safe because the object values
control the interpretation of the formatting string.</p>
</li>
<li>
<p>The formatting string is repeatedly interpreted for as long as
values, to be formatted, are applied to it.</p>
</li>
<li>
<p>A default formatting string is supported which automatically
separates each formatted value by a single space</p>
</li>
<li>
<p>The class operations can be applied to an ostream object, or an
object of any class derived from ostream.</p>
</li>
<li>
<p>The class supports all the format control facilities of ostream
in a form that is easier and more concise to use.</p>
</li>
<li>
<p>The class supports features that are not supported by ostream,
e.g. controlling the case of alphabetic characters.</p>
</li>
<li>
<p>The class uses operator &lt;&lt; () for notational consistency
with ostream.</p>
</li>
<li>
<p>The class saves and restores the ostream format properties so
that it does not interfere with the formatting behaviour of ostream
objects or vice versa.</p>
</li>
<li>
<p>The default formatting of the class can be overridden on a
per-object basis.</p>
</li>
<li>
<p>A client class T can provide a &quot;friend Formatter&amp; operator
&lt;&lt; (Formatter&amp;, T&amp;)&quot; operation so that its textual
representation may be formatted.</p>
</li>
<li>
<p>Operations on an ostream object and a Formatter object may be
freely intermixed, in a type-safe way, within a single
expression.</p>
</li>
<li>
<p>The interpretation of the formatting string supports substring
repetition (a la ALGOL 68).</p>
</li>
<li>
<p>It should not be possible for an object of the class Formatter
to be misused (its constructors, destructor, new() and delete()
operations are private; perhaps assignment and comparison should
also be private?).</p>
</li>
</ul>
</div>
<p>The significant features of the Formatter class are shown in the
abbreviated class declaration that follows:</p>
<pre class="programlisting">
// -------- Formatter class declaration -----------
#include &lt;iostream.h&gt;
#include &lt;strstream.h&gt;

class Formatter {
  ostream&amp; dest;
// other private data members
  Formatter () : dest(cout) {};
  Formatter (const Formatter&amp;) :dest(cout) {};
  Formatter (ostream &amp; os, char *form);
  ~Formatter ();
  void * operator new (size_t) {return NULL;};
  void operator delete (void*, size_t) {};
// other private methods
public:
friend Formatter operator % (ostream&amp; os, char *form); // convert an ostream into a Formatter
  Formatter&amp; operator % (char *defaults) ; // change the default formats
  Formatter&amp; operator &lt;&lt; (ostrstream *); // format the text from a memory buffer
  Formatter&amp; operator &lt;&lt; (int); // convert basic data values
  Formatter&amp; operator &lt;&lt; (int *); // into formatted text
  Formatter&amp; operator &lt;&lt; (float);
  Formatter&amp; operator &lt;&lt; (char);
  Formatter&amp; operator &lt;&lt; (char *);
// other member functions that correspond to ostream::operator &lt;&lt;() member functions

  // manipulators that convert a Formatter object back into the ostream object
  // from which it was constructed
friend ostream&amp; endf (Formatter&amp;); // output to end of formatting string
friend ostream&amp; stopf (Formatter&amp;); // stop use of formatting string
friend ostream&amp; endl (Formatter&amp;); // as endf + output of newline
friend ostream&amp; stopl (Formatter&amp;); // as stopf + output of newline
  ostream&amp; operator &lt;&lt; (ostream&amp; (*f) (Formatter&amp;)) {return (*f)(*this);}
static char one_space[2];
};

#define SP Formatter::one_space // default formatting string of a single space separator

// --end of Formatter class declaration --------------------------
</pre></div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e86" id="d0e86"></a>Translation of
values into textual representation</h2>
</div>
<p>Each '%' character in the formatting string acts as a
placeholder in the generated text for the value which will replace
it (unless immediately followed by another '%' when it represents
itself). The characters following a '%' character constitute a
formatting control pattern which determines how the value will be
translated and formatted. A format control pattern is always
terminated by a character which determines the mode of translation
that is to be applied to a value, as defined below.</p>
<div class="table"><a name="d0e91" id="d0e91"></a>
<p class="title c2">Table 1. </p>
<table summary="" border="1">
&lt;colgroup&gt;
&lt;col&gt;
&lt;col&gt;
&lt;col&gt;&lt;/colgroup&gt;
&lt;thead&gt;
<tr>
<th bgcolor="#DDDDDD">Type of value</th>
<th bgcolor="#DDDDDD">Mode character</th>
<th bgcolor="#DDDDDD">Interpretation</th>
</tr>
&lt;/thead&gt;
&lt;tbody&gt;
<tr>
<td bgcolor="#EEEEEE" rowspan="6">Integer</td>
<td>s (default)</td>
<td bgcolor="#EEEEEE">decimal value</td>
</tr>
<tr>
<td>d</td>
<td bgcolor="#EEEEEE">decimal value</td>
</tr>
<tr>
<td>o</td>
<td bgcolor="#EEEEEE">octal value</td>
</tr>
<tr>
<td>O</td>
<td bgcolor="#EEEEEE">octal value with leading 0</td>
</tr>
<tr>
<td>x</td>
<td bgcolor="#EEEEEE">hexadecimal value</td>
</tr>
<tr>
<td>X</td>
<td bgcolor="#EEEEEE">hexadecimal value with leading 0x</td>
</tr>
<tr>
<td bgcolor="#EEEEEE" rowspan="6">float</td>
<td>s (default)</td>
<td bgcolor="#EEEEEE">6 decimal digits</td>
</tr>
<tr>
<td>e</td>
<td bgcolor="#EEEEEE">scientific</td>
</tr>
<tr>
<td>E</td>
<td bgcolor="#EEEEEE">scientific in upper case</td>
</tr>
<tr>
<td>f</td>
<td bgcolor="#EEEEEE">fixed</td>
</tr>
<tr>
<td>g</td>
<td bgcolor="#EEEEEE">full precision format</td>
</tr>
<tr>
<td>G</td>
<td bgcolor="#EEEEEE">full precision format in upper case</td>
</tr>
<tr>
<td bgcolor="#EEEEEE" rowspan="4">string (char *)</td>
<td>s (default)</td>
<td bgcolor="#EEEEEE">leave string as is</td>
</tr>
<tr>
<td>U</td>
<td bgcolor="#EEEEEE">all alphabetic characters in upper case</td>
</tr>
<tr>
<td>L</td>
<td bgcolor="#EEEEEE">all alphabetic characters in lower case</td>
</tr>
<tr>
<td>m</td>
<td bgcolor="#EEEEEE">all alphabetic characters in European case
(leading and after a '_' in upper case; others in lower case)</td>
</tr>
&lt;/tbody&gt;
</table>
</div>
<p>When the translation mode character does not correspond to the
type of the value to be translated the default translation is
applied to the value.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e238" id="d0e238"></a>Controlling
the layout of values</h2>
</div>
<p>The user can control the layout of the generated text by
specifying:</p>
<div class="itemizedlist">
<ul type="disc">
<li>
<p>the field width for a value</p>
</li>
<li>
<p>the justification of a value within its field</p>
</li>
<li>
<p>the precision of scientific and fixed values</p>
</li>
<li>
<p>the character to be used to pad a translated value to a
specified field width</p>
</li>
</ul>
</div>
<p>These layout controls must appear between the '%' character and
the translation mode character in the format: '%WJPFs' where 's' in
one of the above translation mode characters. The allowable
representation for WPJF is summarised below:</p>
<div class="table"><a name="d0e258" id="d0e258"></a>
<p class="title c2">Table 2. </p>
<table summary="" border="1">
&lt;colgroup&gt;
&lt;col&gt;
&lt;col&gt;
&lt;col&gt;&lt;/colgroup&gt;
&lt;thead&gt;
<tr>
<th bgcolor="#DDDDDD">Layout Control</th>
<th bgcolor="#DDDDDD">Value</th>
<th bgcolor="#DDDDDD">Interpretation</th>
</tr>
&lt;/thead&gt;
&lt;tbody&gt;
<tr>
<td bgcolor="#EEEEEE" rowspan="2">width: W</td>
<td>integer</td>
<td bgcolor="#EEEEEE">the field width</td>
</tr>
<tr>
<td>+integer</td>
<td bgcolor="#EEEEEE">he field width and prefix integer values with
their sign default is W == '0' =&gt; minimal width for value</td>
</tr>
<tr>
<td bgcolor="#EEEEEE" rowspan="3">justification: J</td>
<td>.</td>
<td bgcolor="#EEEEEE">default justification (used to separate W
from P)</td>
</tr>
<tr>
<td>&gt;</td>
<td bgcolor="#EEEEEE">right justify</td>
</tr>
<tr>
<td>&lt;</td>
<td bgcolor="#EEEEEE">left justify</td>
</tr>
<tr>
<td bgcolor="#EEEEEE">precision P</td>
<td>integer</td>
<td bgcolor="#EEEEEE">number of digits after decimal point default
is P = '6'</td>
</tr>
<tr>
<td bgcolor="#EEEEEE">fill F</td>
<td>_c</td>
<td bgcolor="#EEEEEE">use character 'c' to pad the field default is
to pad with spaces</td>
</tr>
&lt;/tbody&gt;
</table>
</div>
<p>The default values of W, J, P and F may be changed on a
per-object basis by the application of the &quot;Formatter&amp;
Formatter::operator % (char *defaults)&quot; operation.</p>
<p>In this context the parameter &quot;defaults&quot; is a formatting string
where each format control pattern is interpreted as setting the
defaults for the type of value specified by its translation mode
character; any other characters are ignored.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e345" id="d0e345"></a>Repeated
substrings</h2>
</div>
<p>Alternatively, %W may be followed by a substring enclosed by '{'
and '}'. to specify that the substring is to be interpreted W
times. For example, the format string:</p>
<pre class="programlisting">
&quot;abc%s %4{xy%16ez} %x&quot; 
</pre>
<p>is equivalent to:</p>
<pre class="programlisting">
&quot;abc%s xy%16ezxy%16ezxy%16ezxy%16ez %x&quot;
</pre></div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e356" id="d0e356"></a>Examples of
modus operandi</h2>
</div>
<p>Given the object declarations:</p>
<pre class="programlisting">
int i = 123;
float f = 4567.89;
char s[] = &quot;Format this&quot;;
</pre>
<p>and the following format strings:</p>
<pre class="programlisting">
static char ft1[] = &quot;Formatted: %d %s %f %U &lt;&lt;\n&quot;;
static char ft2[] = &quot;%s||&quot;;
static char ft3[] = &quot;%15_,s&quot;;
</pre>
<p>the following C++ expression will produce the text shown to
their right:</p>
<pre class="programlisting">
cout % ft1 &lt;&lt; i &lt;&lt; i &lt;&lt; f &lt;&lt; s &lt;&lt; endf;  Formatted: 123 123 4567.890137 FORMAT THIS? &lt;&lt;
cout % ft1 &lt;&lt; i &lt;&lt; f &lt;&lt; s &lt;&lt; i &lt;&lt; endf;  Formatted: 123 4567.89 Format this? 123 &lt;&lt;
cout % ft2 &lt;&lt; s &lt;&lt; f &lt;&lt; i &lt;&lt; endl;       Format this||4567.89||123||
cout % ft2 &lt;&lt; s &lt;&lt; f &lt;&lt; i &lt;&lt; stopl;      Format this||4567.89||123
cout % SP &lt;&lt; f &lt;&lt; i &lt;&lt; s;                4567.89 123 Format this
cout % ft3 &lt;&lt; f &lt;&lt; i &lt;&lt; s;               ,,,,,,,,4567.89,,,,,,,,,,,,123,,,,Format this
</pre>
<p>The C++ code:</p>
<pre class="programlisting">
Formatter&amp; fmt = cout % &quot;Prefix: %2{%7s: }Suffix: %5s:\n&quot;;
int i = 123;
for (int j = 0; j &lt; 100; j += 10 ) fmt &lt;&lt; i+j;
for (int k = 100; k &lt; 2000; k += 200 ) fmt &lt;&lt; i+k;
</pre>
<p>will produce:</p>
<pre class="programlisting">
Prefix: 123: 133: Suffix: 143:
Prefix: 153: 163: Suffix: 173:
Prefix: 183: 193: Suffix: 203:
Prefix: 213: 223: Suffix: 423:
Prefix: 623: 823: Suffix: 1023:
Prefix: 1223: 1423: Suffix: 1623:
Prefix: 1823: 2023
</pre></div>
</p>
<p><strong>Notes:</strong>&nbsp;</p>
<p><em>More fields may be available via dynamicdata ..</em></p>
</div>
</channel>
</rss>
