May, 2005
The Format class is distributed as part of the string library. See the string library documentation on how to customise the include.h file for your compiler and for the file list.
This class is intended to provide a more convenient facility for formatting numerical data than is provided by the standard IO classes.
A typical application would look like this
Format F1, F2; ... load attributes into F1, F2; cout << F1 << x << y << F2 << z << endl;
Format F1 would be applied to x and y and F2 to z.
The variables x, y and z can be any of the following types: char, char*, String, int, unsigned int, long, unsigned long, double, float.
The manipulators endl, ends and flush are passed directly through to the ostream (such as cout).
One can also use the code
OstreamWithFormat f1(cout, F1); OstreamWithFormat f2(cout, F2); f1 << x << y; f2 << z << endl;
The attributes are loaded with statements like
F1.precision(2);You can recover their values with statements like
int p = F1.precision();
You can recover a pointer to the Format object from an OstreamWithFormat object , f1, with a statement like
Format& F1 = f1.format();
The following table shows the functions for accessing the attributes (preferred version in bold):
attribute | default value | possible values | description |
min_width MinWidth |
0 | non-negative integer | minimum field width |
max_width MaxWidth |
12 | positive integer | maximum field width |
width Width |
positive integer | sets both min_width and max_width | |
overflow_policy OverFlowPolicy |
Format::E | Format::E | on overflow use scientific format |
Format::HASH | on overflow replace field with # characters | ||
underflow_policy UnderFlowPolicy |
Format::ZERO | Format::E | on underflow use scientific format |
Format::HASH | on underflow replace field with # characters | ||
Format::ZERO | reduce precision | ||
alignment Alignment |
Format::RIGHT | Format::LEFT | left alignment |
Format::RIGHT | right alignment | ||
Format::CENTRE Format::CENTER |
centre (center) alignment | ||
format_type FormatType |
Format::SIG_FIGS | Format::SIG_FIGS | precision shows number of significant figures |
Format::DEC_FIGS | precision shows number of decimal figures | ||
Format::SCIENTIFIC | scientific (E) format | ||
Format::INTEGER | round to an integer | ||
positive Positive |
Format::NX | Format::PLUS | non-negative numbers preceded by + |
Format::SPACE | non-negative numbers preceded by space | ||
Format::NX | no additional character preceding non-negative number | ||
precision Precision |
2 | non-negative integer | number of decimal or significant figures |
prefix Prefix |
"" | String or char* | prefix string |
suffix Suffix |
"" | String or char* | suffix string |
separator Separator |
"," | String or char* | separator string |
variant Variant |
Format::VAR0 | Format::VAR0 | default setting |
Format::VAR1 | Affects SIG_FIGS and DEC_FIGS formats. For number less than 1 in absolute value, there is no 0 before the decimal point; number with no decimal places will have a decimal point if there is room. |
min_width sets the minimum field width and max_width the maximum field width. The program uses the smallest width required to present the number to the required precision and format type. If this is less than the minimum field width spaces are inserted to reach the desired field width. If the number won't fit within the maximum field width the action taken depends on the overflow or underflow policy.
The prefix and suffix strings are printed before and after the field. Their space is in addition to the space set by min_width and max_width.
The separator string is for use by other libraries when outputting data structures.
Variant = Format::VAR1 can give a better layout in columns of numbers using the SIG_FIGS format. Use a width value 2 more than the precision.
Integer objects use only the width, alignment, over flow policy, prefix and suffix properties. Convert an integer to double if you really want a decimal or scientific format type.
char* and String objects use only the width, alignment, prefix and suffix properties. Special characters such as \n are unlikely to be handled correctly.
char objects always use a field width of 1 and ignore the format properties.
To use the format library you need #include "format.h" in your .cpp files.
// Scientific format Format SCI; SCI.FormatType(Format::SCIENTIFIC); SCI.Precision(8); SCI.Width(14); SCI.Suffix("|"); // Decimal format - switch to scientific on under-flow or over-flow Format DEC1; DEC1.UnderFlowPolicy(Format::E); DEC1.FormatType(Format::DEC_FIGS); DEC1.Precision(4); DEC1.Width(12); DEC1.Suffix("|"); // Decimal format - no action on under-flow; hashes on over-flow Format DEC2; DEC2.OverFlowPolicy(Format::HASH); DEC2.FormatType(Format::DEC_FIGS); DEC2.Precision(4); DEC2.Width(12); DEC2.Suffix("|"); // Significant figures - switch to scientific on under-flow or over-flow Format SIG1; SIG1.UnderFlowPolicy(Format::E); SIG1.FormatType(Format::SIG_FIGS); SIG1.Precision(8); SIG1.Width(11); SIG1.Positive(Format::SPACE); SIG1.Prefix(" "); SIG1.Suffix("|"); // Significant figures - reduce precision on under-flow; hashes on over-flow Format SIG2; SIG2.OverFlowPolicy(Format::HASH); SIG2.FormatType(Format::SIG_FIGS); SIG2.Precision(8); SIG2.Width(11); SIG2.Positive(Format::SPACE); SIG2.Prefix(" "); SIG2.Suffix("|"); // Significant figures - reduce precision on under-flow; // scientific on over-flow; VAR1 variant Format SIG3; SIG3.UnderFlowPolicy(Format::ZERO); SIG3.OverFlowPolicy(Format::E); SIG3.FormatType(Format::SIG_FIGS); SIG3.Precision(8); SIG3.Width(10); SIG3.Positive(Format::SPACE); SIG3.Prefix(" "); SIG3.Suffix("|"); SIG3.Variant(Format::VAR1); // Integer format - switch to scientific on over-flow Format INT; INT.FormatType(Format::INTEGER); INT.Width(12); double x = 1.23456789; double mult[] = {0, 1E-100, 1E-20, 0.0001, 0.1, 1, 10, 1000, 1E7, 1E8, 1E9, 1E10, 1E20, 1E100}; cout << SCI << "SCIENTFIC" << DEC1 << "DEC 1" << DEC2 << "DEC 2" << SIG1 << "SIG 1" << SIG2 << "SIG 2" << SIG3 << "SIG 3" << INT << "INTEGER" << endl; for (i = 0; i < 14; ++i) { double y = x * mult[i]; cout << SCI << y << DEC1 << y << DEC2 << y << SIG1 << y << SIG2 << y << SIG3 << y << INT << y << endl; } cout << endl;
produces this output
SCIENTFIC| DEC 1| DEC 2| SIG 1| SIG 2| SIG 3| INTEGER 0.0000000e+00| 0.0000| 0.0000| 0.0000000| 0.0000000| .00000000| 0 1.2345679e-100| 1.2346e-100| 0.0000| 1.235e-100| 0.00000000| .00000000| 0 1.2345679e-20| 1.2346e-20| 0.0000| 1.2346e-20| 0.00000000| .00000000| 0 1.2345679e-04| 1.2346e-04| 0.0001| 1.2346e-04| 0.00012346| .00012346| 0 1.2345679e-01| 1.2346e-01| 0.1235| 0.12345679| 0.12345679| .12345679| 0 1.2345679e+00| 1.2346| 1.2346| 1.2345679| 1.2345679| 1.2345679| 1 1.2345679e+01| 12.3457| 12.3457| 12.345679| 12.345679| 12.345679| 12 1.2345679e+03| 1234.5679| 1234.5679| 1234.5679| 1234.5679| 1234.5679| 1235 1.2345679e+07|1.234568e+07|############| 12345679| 12345679| 12345679.| 12345679 1.2345679e+08|1.234568e+08|############| 123456790| 123456790| 123456790| 123456789 1.2345679e+09|1.234568e+09|############| 1234567900| 1234567900| 1.235e+09| 1234567890 1.2345679e+10|1.234568e+10|############| 1.2346e+10| ###########| 1.235e+10| 12345678900 1.2345679e+20|1.234568e+20|############| 1.2346e+20| ###########| 1.235e+20|1.234568e+20 1.2345679e+100|1.23457e+100|############| 1.235e+100| ###########| 1.23e+100|1.23457e+100