CS170 Lab: Unix I/O Redirection, Pipes, Unix Sort
Highlights of this lab:
Lab Exercise:
Unix I/O Redirection, Pipes, Sort, cerr.
Unix I/O Redirection
Generally when you enter a Unix command or the name of a C++
executable file, you expect:
- Input from the keyboard.
This is the standard input stream.
Historically, the keyboard was part of the
console
terminal connected to the Unix system.
This explains the
c in the C++
cin function.
- Output to the screen.
This is the standard output stream.
Historically, the screen was part of the
console
terminal connected to the Unix system.
This explains the
c in the C++
cout function.
Here are a couple of little examples:
- ls
<-- A Unix command with output going to the screen.
hello.cpp hello
- hello
<-- The name of a C++ executable file;
keyboard input, screen output.
Please enter your name: Jane Doe
Hello Jane Doe. Welcome to CS170.
For simple processing, keyboard input and screen output is adequate.
However there are times when you need to deal with large amounts of data
that make this conventional I/O processing cumbersome or even unworkable.
You could get around this in a C++ program by changing your program
to use file I/O.
But there is a simpler work-around for both Unix
commands and for C++ executables.
This work-around is I/O Redirection and is implemented
very simply with these operators:
- Use <
to redirect input from the keyboard to a specified file or process.
- Use >
to redirect output from the screen to a specified file or process.
- Use >>
to append (add) output to the end of an existing file.
|
The following example shows how to redirect and append output:
venus[6]% cal 06 2005 <-- The cal command with no redirection.
June 2005
S M Tu W Th F S
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30
venus[7]% cal 06 2005 > months <-- The cal command redirecting output to a file.
venus[8]% cat months <-- Using the cat command to view the file.
June 2005
S M Tu W Th F S
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30
venus[9]% cal 07 2005 >> months <-- The cal command appending to a file.
venus[10]% cat months <-- Using the cat command to view the file.
June 2005
S M Tu W Th F S
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30
July 2005
S M Tu W Th F S
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31
Unix Pipes, Sort
Redirection of I/O is quick and easy as just shown.
However what if you wanted the output of one process to become
the input of another, different process?
i.e. You want to establish a pipeline between the processes.
To do this, you can connect the 2 processes by the vertical bar -
| - on the command line.
The following example illustrates a pipe between the
cat command
and the Unix
sort command.
cat command used by itself:
venus[11]% cat namelist
Cotescu
Zimmer
Feldstrom
Anderson
Masterson
sort command used by itself:
venus[12]% sort namelist
Anderson
Cotescu
Feldstrom
Masterson
Zimmer
cat command and sort command pipelined together:
venus[13]% cat namelist | sort
Anderson
Cotescu
Feldstrom
Masterson
Zimmer
venus[86]%
Of course you can use a pipe with other Unix commands, not just
the sort command.
For example to have the output of the ls command
directed to the input of the lpr (or print) command,
you could enter:
ls | lpr -Pc122
For another explanation of this topic
you may refer to the following link:
Unix I/O Redirection and Pipes
C++ cerr Stream
While we are on the topic of I/O redirection and streams, there is
one last I/O topic you should be aware of.
As mentioned previously, when you run a C++ program you expect:
- Input from the keyboard.
This is the standard input stream
implemented by the
cin function.
- Output to the screen.
This is the standard output stream
implemented by the
cout function.
You should also be aware of a third stream:
- The standard error stream
implemented by the
cerr function.
Normally, the data generated by a
cerr
call is directed to the same place as standard output i.e. the console screen.
The major difference is that:
- Data you send via
cout
is buffered
which means that data is not output after each individual cout
statement.
The operating system accumulates the data and outputs it in
a group to expedite processing.
- Data you send via
cerr
is non-buffered
which means that data is output immediately after
each individual cout statement.
So why should you be concerned?
Well, if your program runs normally, you will notice no difference at all
if you have both cout and cerr statements in your program.
However, think about what might happen if you had
some cout statements in your program reporting on
conditions that might be problematic.
If your program crashes, those error messages might still be
in the output buffer and therefore not get printed out at all!
But if your warning/diagnostic messages are in cerr statments, then
you can be sure they will be not be lost.
Therefore it is a good idea to use
cerr
in your C++ programs when you want to output messages about possible
problems.
Here is a simple little example of a program using cerr:
#include
using namespace std;
int main ()
{
int op1, op2;
cout << "This program inputs 2 numbers and"
<< " divides the first by the second." << endl;
cout << "Enter first number please: ";
cin >> op1;
cout << endl << "Enter second number please: ";
cin >> op2;
if ( op2 ==0)
cerr << endl <<"Warning!! Cannot divide by zero" << endl;
cout << endl << op1 << " divided by " << op2 << " is: " << op1/op2 << endl;
} // end main
|
Lab Exercise:
Copyright: Department of Computer Science, University of Regina.