Input/Output: Redirection and piping

Using the StdIn in Terminal

Typing input. When you use the java command to invoke a Java program from the command line, you actually are doing three things:

(1) issuing a command to start executing your program,

(2) specifying the values of the command-line arguments, and

(3) beginning to define the standard input stream. The string of characters that you type in the terminal window after the command line is the standard input stream.

For example, AddInts.java takes a command-line argument n, then reads n numbers from standard input and adds them, and prints the result to standard output:

/******************************************************************************
 *  Compilation:  javac AddInts.java
 *  Execution:    java AddInts
 *  Dependencies: StdIn.java StdOut.java
 *  
 *  This program takes a command-line argument n, reads in n integers,
 *  and prints out their sum.
 *
 *  % java AddInts n
 *
 ******************************************************************************/

public class AddInts { 
    public static void main(String[] args) { 
        int n = Integer.parseInt(args[0]);
        int sum = 0;
        for (int i = 0; i < n; i++) {
            int value = StdIn.readInt();
            sum = sum + value;
        }
        StdOut.println("Sum is " + sum);
    }
}

Input format. If you type abc or 12.2 or true when StdIn.readInt() is expecting an int, then it will respond with an InputMismatchException. StdIn treats strings of consecutive whitespace characters as identical to one space and allows you to delimit your numbers with such strings.

Interactive user input. TwentyQuestions.java is a simple example of a program that interacts with its user. The program generates a random integer and then gives clues to a user trying to guess the number. The fundamental difference between this program and others that we have written is that the user has the ability to change the control flow while the program is executing.

/******************************************************************************
 *  Compilation:  javac TwentyQuestions.java
 *  Execution:    java TwentyQuestions
 *  Dependencies  StdIn.java
 *
 *  % java TwentyQuestions 
 *  I'm thinking of a number between 1 and 1,000,000 
 *  What's your guess? 500000 
 *  Too high 
 *  What's your guess? 250000 
 *  Too low 
 *  What's your guess? 375000 
 *  Too high 
 *  What's your guess? 312500 
 *  Too high 
 *  What's your guess? 300500 
 *  Too low 
 *  ... 
 *
 ******************************************************************************/

public class TwentyQuestions {

    public static void main(String[] args) {

        // Generate a number and answer questions
        // while the user tries to guess the value.
        int secret = 1 + (int) (Math.random() * 100);

        StdOut.print("I'm thinking of a number ");
        StdOut.println("between 1 and 100");
        int guess = 0; 
        while (guess != secret) {

            // Solicit one guess and provide one answer
            StdOut.print("What's your guess? ");
            guess = StdIn.readInt();
            if      (guess == secret) StdOut.println("You win!");
            else if (guess  < secret)  StdOut.println("Too low ");
            else if (guess  > secret)  StdOut.println("Too high");
        }
    }
} 


Redirection and piping

In terminal:

/******************************************************************************
 *  Compilation:  javac RandomSeq.java
 *  Execution:    java RandomSeq n
 *
 *  Prints n random real numbers between 0 and 1.
 *
 *  % java RandomSeq 5
 *  0.1654760343787165
 *  0.6212262060326124
 *  0.631755596883274
 *  0.4165639935584283
 *  0.4603525361488371
 *
 ******************************************************************************/

public class RandomSeq { 
    public static void main(String[] args) {

        // command-line argument
        int n = Integer.parseInt(args[0]);

        // generate and print n numbers between 0 and 1
        for (int i = 0; i < n; i++) {
            System.out.println(Math.random());
        }
    }
}

Redirecting standard output to a file

java RandomSeq 1000 > data.txt

This command will display data by a window of data at a time.
more < data.txt

Processing an arbitrary-size input stream. Typically, input streams are finite: your program marches through the input stream, consuming values until the stream is empty. But there is no restriction on the size of the input stream. Average.java reads in a sequence of real numbers from standard input and prints their average.

Redirecting standard output from a file

java Average < data.txt

/******************************************************************************
 *  Compilation:  javac Average.java
 *  Execution:    java Average < data.txt
 *  Dependencies: StdIn.java StdOut.java
 *  
 *  Reads in a sequence of real numbers, and computes their average.
 *
 *  % java Average
 *  10.0 5.0 6.0
 *  3.0 7.0 32.0
 *  
 *  Average is 10.5
 *
 *  Note  signifies the end of file on Unix.
 *  On windows use .
 *
 ******************************************************************************/

public class Average { 
    public static void main(String[] args) { 
        int count = 0;       // number input values
        double sum = 0.0;    // sum of input values

        // read data and compute statistics
        while (!StdIn.isEmpty()) {
            double value = StdIn.readDouble();
            sum += value;
            count++;
        }

        // compute the average
        double average = sum / count;

        // print results
        StdOut.println("Average is " + average);
    }
}

Connecting two programs
java RandomSeq 1000000 | java Average

Filters:
more allows you to display a window of data at a time:
java RandomSeq 1000 | more

Guess what this one does:
java RandomSeq 5 | sort

Note: Look at the book site for great illustrations on both redirection and piping.

Classwork:
Go to the Required Submission paragraph for specifics on how to turn in a copy of your terminal session on today’s classwork/activities.