I/O Redirection with Unix

In your C++ programs, writing to cout writes to the standard output, which is the display, by default. Reading from cin reads from the standard input, which is the keyboard, by default.

The Unix shell permits both of these defaults to be changed, so that your program, without being edited and recompiled, can read and/or write disk files. This is called I/O redirection.

Redirection means your program still writes to cout and reads from cin, but these variables are connected to disk files instead of the display and the keyboard.


Example: An Interactive Test Driver

Suppose you've written a function, isPrime(), that you would like to test.

One good way to test it is to write an an interactive driver, isPdriver.C:

int isPrime(long n);

void main(){
   int n;   //input integer

   //prompt for input
   cout << "Enter n > 1 (cntrl-d to Exit): ";
   cin >> n;

   //driver loop
   while(cin){
     //print whether n is prime
     cout  << endl << n << (isPrime(n)?" is ":" is not ") << " prime. ";
     //prompt and read n
     cout << "Enter n > 1 (cntrl-d to Exit): ";
     cin >> n;
   }
}

Example: A Batch-Mode Test Driver using I/O Redirection

The interactive test driver is a bit slow because you have to enter each of the test values at run time. Furthermore, the same set of test values has to be entered at runtime everytime you modify the function.

With a batch-mode test driver, you just type the test values into an input file, and then run the driver on the input file as many times as you want.

To do this, simply remove prompts from the interactive driver by turning them into comments (but do NOT remove the cin statements):

int isPrime(long n);

void main(){
   int n;   //input integer

   //prompt for input
   //cout << "Enter n > 1 (cntrl-d to Exit): ";
   cin >> n;

   //driver loop
   while(cin){
     //print whether n is prime
     cout  << endl << n << (isPrime(n)?" is ":" is not ") << " prime. ";
     //prompt and read n
     //cout << "Enter n > 1 (cntrl-d to Exit): ";
     cin >> n;
   }
}

To run the test driver using I/O redirection

  1. Use emacs to create an input file, isPrime.in, and type in a test set of integers (all on one line, or one per line).
    17  9  3  4  5  11  7  32767
    

  2. Redirect cin to read from the input file:

    % isPDriver < isPrime.in

    The program output will be displayed on the screen.

  3. cout may be redirected to a disk file with this command:

    % isPDriver > isPrime.out

    The user will have to enter the input from the keyboard.

  4. Both cin and cout can be redirected at once with this command:

    % isPDriver < isPrime.in > isPrime.out

  5. The output file can be examined from the command line (use the command "more isPrime.in"), or opened with emacs (use the c-x c-f command in emacs).

Appending the output to a file: >>

The append output symbol (>>) causes the shell to add the output to the end of file, leaving intact any information that was there.

noclobber

Depending on what Unix shell you are using and how your Unix environment has been set up, the shell may display an error message and not overwrite the contents of an existing file when you use redirection. For example, if isPrime.out already exists, this command may cause the shell to display the error "File exists".

% isPDriver < isPrime.in > isPrime.out

This happens when the noclobber feature is enabled; otherwise the file is overwritten with no error message.

The C shell, tcshell, Korn shell, and other shells provide an environment feature called noclobber that stops you from overwriting an existing file using redirection (it does not stop you from overwriting an existing file using mv or cp). It also prevents you from creating a file when you attempt to append to a file that does not exist.

To override noclobber, add an exclamation point to the symbol you use for redirecting or appending output: >! and >>!

Example: Overwrite existing file.

% isPDriver < isPrime.in >! isPrime.out


Home