7. Input and Output


Textual input and output

A program needs some way of communicating with the user. The two most common ways to do that are:

Graphical input and output is important, but it is a big topic, and is not the focus of this course. We will restrict ourselves to textual input and output. A program reads information that the user types on the keyboard, and writes or prints information into a terminal window. (The terms write and print are generally used interchangeably when discussing textual output.)


Standard input and standard output

Standard output

A program writes on the terminal by writing to the standard output. For brevity, I will refer to the standard output as stdout.

By default, stdout is the terminal. But you can redirect it so that anything written to stdout goes into a file instead.

Output redirection is a feature of Linux (and other operating systems, including Windows), not of C++. To redirect stdout to file F, write >F after a Linux command. For example,

  jump up >jump-out.txt
runs command
  jump up
with the standard output going to file jump-out.txt.


Standard input

To read from the keyboard, use the standard input. For brevity, I will refer to the standard input as stdin.

By default, stdin is the keyboard, but you can redirect stdin so that it comes from a file. To make stdin come from file F, add <file to the end of a Linux command. For example,

  jump up <data.txt
runs command
      jump up
but arranges for its standard input to come from file data.txt. That is very useful for testing. If you just put a test input in a file, then you don't need to type it again each time you modify your program.


Redirecting both stdin and stdout

To redirect both stdin and stdout, put both redirections at the end of a command, in either order. For example,

  ./foo <data.txt >jump-out.txt
runs command
  ./foo
with stdin coming from file data.txt and stdout going to file jump-out.txt.



Printf

The <cstdio> library is a popular one for writing information. To use it #include <cstdio>.

To print string s, use printf(s);. For example, statement

  printf("Have a nice day.\n");
writes Have a nice day on stdout. Notice character sequence \n in the string. It is an end-of-line indicator, usually abbreviated to newline. A line ends only when you explicitly end it. For example,
  printf("Have a ");
  printf("nice day.\n");
writes
Have a nice day.
Don't forget to end lines, or your output will be unreadable.

Printf can actually take any number of parameters. Printf is short for "print formatted", and the string can contain value designators, each starting with %. Printf substitutes the value of the n-th parameter after the initial string for the n-th value designator. For example, suppose that x is 25 and y is 500. Then

  printf("x = %i and y = %i\n", x, y)
writes string "x = 25 and y = 500\n" to the standard output.

Value designators

Value designators include the following.

%i
%d

The value has type int. Show it as a (decimal) integer. (%i is the same as %d. The d stands for decimal.)

%5i
%5d

These are like %i and %d, but use at least 5 characters by adding spaces on the left-hand side as necessary. (If the number needs more than 5 characters then it will not be shortened.)

For example,

  printf("%6i%4i\n", 45, 300);
  printf("%6i%4i\n", 25000, 2);
  printf("%6i%4i\n", 500, 27);
writes
    45 300
 25000   2
   500  27

Number 5 in %5i is called a field width. All of the value designators allow a field width.


%−5i

Like %5i, but put the spaces on the right side instead of on the left side. All value designators allow a negative field width.

%li

Like %i, but the value has type long. Notice that this is %li, with a lower-case ℓ.

%lf
%10.2lf

Show a number of type double. %10.2lf shows the number using a total of at least 10 characters, with 2 digits shown to the right of the decimal point. For example, if variable stddev has value 450.346, then
  printf("The standard deviation is %10.2lf\n", stddev
prints
The standard deviation is     450.35.
Large numbers will not be cut off to force them to fit into the designated field width. So
  printf("The standard deviation is %0.2lf\n", stddev
prints
The standard deviation is 450.35.
with no padding.

In %lf, The lower-case ℓ stands for 'long', since type double is sometimes referred to as 'long float'.


%10.2le

Like %lf, but use E format, showing the value using scientific notation. Use this for showing very large or very small values.

%*i

If the field width is given by an asterisk, the width is taken from a parameter. So this actually uses two of the parameters after the format, the field width then the integer to show. For example,
  printf("%*i", n, x);
shows the value of integer x with a field width of n.

Putchar

Statement

  putchar(c);
is equivalent to
  printf("%c", c);
but putchar is much more efficient.

Examples

Statement

  printf("My sister is named %s and she is %i years old\n", "Laura", 10);
writes
 My sister is named Laura and she is 10 years old
Be sure not to forget to add \n if you want to end the line. Statements
  printf("I am ");
  printf("anxious to finish\n");
writes
  I am anxious to finish
Also do not forget spaces. Statement
  printf("%i%i\n", 25, 32);
writes
  2532


Scanf

The <cstdio> library also provides a function, scanf, for reading information from stdin. Be sure to #include the <cstdio> library to use scanf.

The <cstdio> library is a library for C. C++ programs can use it, but to fully understand what is going on, we need to talk about memory addresses.

Using scanf

The first parameter of scanf is a format string describing the things to be read. After that is a list of memory addresses of variables the results should be put. The memory address of variable z is written &z. For example, statement

  scanf("%i%i", &x, &y);
reads two integers and stores them into variables x and y, which must have type int. The first value goes into x and the second one into y. Formats for reading include

  • %li (read a long integer);
  • %f (read a value of type float);
  • %lf (read a value of type double);
  • a space in an input format indicates that an arbitrary amount of white space (spaces, tabs, end-of-line characters) should be skipped.

What if the read cannot be done?

Sometimes a read cannot be accomplished. For example, if you ask to read an integer, but the program sees abc, then it cannot read the integer. scanf stops reading at the first failure and returns the number of items successfully read. So

  int status = scanf("%i%i", &x, &y);
  if(status < 2)
  {
    what to do if it was not possible to read both x and y
  }
is a typical way to use scanf.

If scanf encounters the end of a file without reading any of the items sought, it returns EOF, which is a name for −1.


Prompts

When a program reads information from the standard input, it usually writes something to let the user know to type the required information. For example,
  printf("What number should I use? ");
  scanf("%i", &num);
But do not overdo it. If the input is supposed to have a particular rigid form, don't write a prompt for each line. It is annoying.


Don't confuse reading and writing with parameters and return values

Some students confuse reading from stdin and writing to stdout with parameter passing and returning values from functions. Here is a function that computes the square of a real number.

  double sqr(double x)
  {
    return x*x;
  }
Students who become confused with input and output write
  double sqr(double x)
  {
    printf("What is x ");
    scanf("%lf", &x);
    printf("The square of %lf is %lf\n", x, x*x);
  }
That makes no sense. The parameter, x, represents information passed from sqr's caller to sqr. Don't try to get that information from some other source. The result is passed back to the caller, not written for the user to look at.

In a large piece of software, only a small percentage of functions do input or output. Most of the time, functions communicate with one another through parameters and returned values.


Exercises

  1. Suppose that variable mass is an integer (type int). Write a printf statement that writes

    This thing's mass is ... kilograms
    
    where the ... has been replaced by the value of mass. Write an end-of-line at the end of it. Answer

  2. Repeat the previous question, but this time assume that variable mass has type double. Answer

  3. Write a definition of procedure writeSpaces(n), which writes n spaces. Assume that n is at least 1. Answer