PHYCS 3730/6720 Lab Exercise

Reading and references: Tables of numbers are easier to read if the columns line up. Here we practice with numeric output format. We will start with cout, but also discuss the ANSI C function printf.

Output formatting with cout is rather cumbersome. Flowers introduces an elegant format class that makes it somewhat less tedious, but before using it one should understand the basics. The C function printf does the job in a more flexible and compact style, so it is useful to learn it.

Exercise 1. ios format control manipulators

When you use cout you access the member functions and constants of the ios class. This class is defined when you include the iostream.h header. Flowers gives an abbreviated version of the format control members of the ios class on p. 134. The ios class has three formatting member functions flags, precision, width and some constants left, right, fixed, etc.

Here is an example of how they can be used to generate a table of x, y values. The sample program just reads the numbers from standard input and prints them in columns on standard ouptut.

   #include <iostream.h>
     ...
   double x,y;
     ...

   // Set 4 digits past decimal
   cout.precision(4);     
   // Specify right-adjusted numbers in fixed format (xxx.xxxx)
   // Note: Multiple options are added and then passed to flags.
   cout.flags(ios::right + ios::fixed);
   // Write a column header
   cout >> "\n  x     y\n";
   cout >> "--------------\n";
   while(1){
     cin >> x >> y;
     if(cin.eof())break;  // Stop on end-of-file
     // Specify 7 character field width.  Must be done for each value.
     cout.width(7);
     cout << x;
     cout.width(7);
     cout << y << "\n";
   }

Create a data file with a list of x and y values. Vary the numbers with some in scientific notation with a variety of powers of 10. Compile the above code and experiment with field widths, justification, precision and switching fixed on and off. See what happens if the number is too small to represent with the number of digits given. See what defaults are used if you omit one or more of the formatting specifications.


Exercise 2. printf

Here is how to do the same thing with the ANSI C function printf.
   #include <iostream.h>
   #include <stdio.h>
     ...
   double x,y;
     ...

   // Write a column header
   printf("\n  x     y\n");
   printf("--------------\n");
   while(1){
     cin >> x >> y;
     if(cin.eof())break;  // Stop on end-of-file
     printf("%7.4f%7.4f\n",x,y);
   }
If you use printf you must include stdio.h. The first argument of the function printf is a format string. The remaining arguments list the values to be written. For writing the column header, we have no values other than a couple of fixed strings. Now let's look at the printf statement that writes x and y. The percent signs % in the format string introduce the format conversion specification. There are two of them, one for each value written. They are taken in order reading from left to right. Each output value should have a corresponding format specification. The 7.4 specifies a field width of 7 and 4 digits past the decimal point. The f specifies "fixed" format (i.e. not scientific notation with powers of 10). Omitting the field width is OK, but then you can't line up the numbers. The field width is actually treated as a minimum request. If the value requires more space than you allow, printf will take more space. Of course, the numbers won't line up, then, but that is much preferable to a misleading truncation.

Other than format conversion specifications, any characters in the format string are copied into the output as given. In this example the end-of-line "\n" is such a character. Here are some commonly used format conversion specifications. The specification must be agree with the numeric type shown.

The g format produces either f, e or d type output depending on the magnitude of the number and whether there are only zeros after the decimal point. This is just like the default behavior of cout. The string conversion can also take a width specification as in %ws.

Experiment with the above code. Try adding a line number as an integer. Try varying the width. Try adding a vertical bar | character between the columns.