Thursday, 26 April 2018

Core Java: Formatted Input/ Output

Formatted Output via "printf()" (JDK 1.5)
 
System.out.print() and println() do not provide output formatting, such as controlling the number of spaces to print an int and the number of decimal places for a double.
 
Java SE 5 introduced a new method called printf() for formatted output (which is modeled after C Language's printf()). printf() takes the following form:
printf(formatting-string, arg1, arg2, arg3, ... );
 
Formatting-string contains both normal texts and the so-called Format Specifiers. Normal texts (including white spaces) will be printed as they are. Format specifiers, in the form of "%[flags][width]conversion-code", will be substituted by the arguments following the formatting-string, usually in a one-to-one and sequential manner. A format specifier begins with a '%' and ends with the conversion code, e.g., %d for integer, %f for floating-point number, %c for character and %s for string. Optional [width] can be inserted in between to specify the field-width. Similarly, optional [flags] can be used to control the alignment, padding and others. For examples,
 
·        %αd: integer printed in α spaces (α is optional).
 
·        %αs: String printed in α spaces (α is optional). If α is omitted, the number of spaces is the length of the string (to fit the string).
 
·        %α.βf: Floating point number (float and double) printed in α spaces with β decimal digits (α and β are optional).
 
·        %n: a system-specific new line (Windows uses "\r\n", Unix and Mac "\n").
 
Examples:
 
System.out.printf("Hello%2d and %6s", 8, "HI!!!%n");
Hello*8 and ****HI!!!   // * denotes white-spaces inserted by format specifier
System.out.printf("Hi,%s%4d%n", "Hello", 88);
Hi,Hello**88
System.out.printf("Hi, %d %4.2f%n", 8, 5.556);
Hi, 8 5.56
System.out.printf("Hi,%-4s&%6.2f%n", "Hi", 5.5);  // '%-ns' for left-align String
Hi,Hi**&**5.50
System.out.printf("Hi, Hi, %.4f%n", 5.56);
Hi, Hi, 5.5600
 
Take note that printf() does not advance the cursor to the next line after printing. You need to explicitly print a newline character at the end of the formatting-string to advance the cursor to the next line, if desires. [In C program, we often use '\n' to print a newline, which results in non-portable program. You should use format specifier "%n" instead.]
 
There are many more format specifiers in Java. Refer to JDK Documentation for the detailed descriptions.
 
(Also take note that printf() take a variable number of arguments (or varargs), which is a new feature introduced in JDK 1.5 in order to support printf())
  
Input From Keyboard via "Scanner" (JDK 1.5)
 
Java, like all other languages, supports three standard input/output streams: System.in (standard input device), System.out (standard output device), and System.err (standard error device). The System.in is defaulted to be the keyboard; while System.out and System.err are defaulted to the console. They can be re-directed to other devices, e.g., it is quite common to redirect System.err to a disk file to save these error message.
 
You can read input from keyboard via System.in (standard input device).
Java SE 5 introduced a new class called Scanner in package java.util to simplify formatted input (and a new method printf() for formatted output described earlier). You can construct a Scanner to scan input from System.in (keyboard), and use methods such as nextInt(), nextDouble(), next() to parse the next int, double and String token (delimited by white space of blank, tab and newline).
 
/*
 * Testing input scanner
 */
import java.util.Scanner;    // Needed to use the Scanner
public class ScannerTest {
   public static void main(String[] args) {
      // Declare variables
      int num1;
      double num2;
      String str;
      // Construct a Scanner named "in" for scanning System.in (keyboard)
      Scanner in = new Scanner(System.in);

      // Read inputs from keyboard
      System.out.print("Enter an integer: ");  // Show prompting message
      num1 = in.nextInt();         // Use nextInt() to read an int
      System.out.print("Enter a floating point: ");  // Show prompting message
      num2 = in.nextDouble();      // Use nextDouble() to read a double
      System.out.print("Enter a string: ");  // Show prompting message
      str  = in.next();            // Use next() to read a String token, up to white space

      // Formatted output via printf()
      System.out.printf("%s, Sum of %d & %.2f is %.2f%n", str, num1, num2, num1+num2);

      // close the input
      in.close();
   }
}
 
You can also use method nextLine() to read in the entire line, including white spaces, but excluding the terminating newline.
/*
 * Testing Scanner's nextLine()
 */
 
import java.util.Scanner;    // Needed to use the Scanner
public class ScannerNextLineTest {
   public static void main(String[] args) {
      Scanner in = new Scanner(System.in);
      System.out.print("Enter a string (with space): ");
      // Use nextLine() to read entire line including white spaces,
      //   but excluding the terminating newline.
      String str  = in.nextLine();       
      System.out.printf("%s%n", str);
      in.close();
   }
}
 
Try not to mix nextLine() and nextInt()|nextDouble()|next() in a program (as you may need to flush the newline from the input buffer).
 
The Scanner supports many other input formats. Check the JDK documentation page, under package java.util ⇒ class Scanner ⇒ Method.

 Input from Text File via "Scanner" (JDK 1.5)

 
Other than scanning System.in (keyboard), you can connect your Scanner to scan any input source, such as a disk file or a network socket, and use the same set of methods nextInt(), nextDouble(), next(), nextLine() to parse the next int, double, String and line. For example,
 
Scanner in = new Scanner(new File("in.txt"));  // Construct a Scanner to scan a text file
 
// Use the same set of methods
int anInt = in.nextInt();         // next String
double aDouble = in.nextDouble(); // next double
String str = in.next();           // next int
String line = in.nextLine();      // entire line
 
To open a file via new File(filename), you need to handle the so-called FileNotFoundException, i.e., the file that you are trying to open cannot be found. Otherwise, you cannot compile your program. There are two ways to handle this exception: throws or try-catch.
 
/*
 * Input from File.
 * Technique 1: Declare "throws FileNotFoundException" in the enclosing main() method
 */
 
import java.util.Scanner;               // Needed for using Scanner
import java.io.File;                    // Needed for file operation
import java.io.FileNotFoundException;   // Needed for file operation
public class TextFileScannerWithThrows {
   public static void main(String[] args)
          throws FileNotFoundException {  // Declare "throws" here
      int num1;
      double num2;
      String name;
      Scanner in = new Scanner(new File("in.txt"));  // Scan input from text file
      num1 = in.nextInt();      // Read int
      num2 = in.nextDouble();   // Read double
      name = in.next();         // Read String
      System.out.printf("Hi %s, the sum of %d and %.2f is %.2f%n", name, num1, num2, num1+num2);
      in.close();
   }
}
 
To run the above program, create a text file called in.txt containing:
1234
55.66
Paul
/*
 * Input from File.
 * Technique 2: Use try-catch to handle exception
 */
 
import java.util.Scanner;               // Needed for using Scanner
import java.io.File;                    // Needed for file operation
import java.io.FileNotFoundException;   // Needed for file operation
public class TextFileScannerWithCatch {
   public static void main(String[] args) {
      int num1;
      double num2;
      String name;
      try {                                // try these statements
         Scanner in = new Scanner(new File("in.txt"));
         num1 = in.nextInt();      // Read int
         num2 = in.nextDouble();   // Read double
         name = in.next();         // Read String
         System.out.printf("Hi %s, the sum of %d and %.2f is %.2f%n", name, num1, num2, num1+num2);
         in.close();
      } catch (FileNotFoundException ex) {  // catch and handle the exception here
         ex.printStackTrace();              // print the stack trace
      }
   }
}

 Formatted Output to Text File

 
Java SE 5.0 also introduced a so-called Formatter for formatted output (just like Scanner for formatted input). A Formatter has a method called format(). The format() method has the same syntax as printf(), i.e., it could use format specifiers to specify the format of the arguments. Again, you need to handle the FileNotFoundException.
/*
 * Output to File.
 * Technique 1: Declare "throws FileNotFoundException" in the enclosing main() method
 */
import java.io.File;
import java.util.Formatter;             // <== note
import java.io.FileNotFoundException;   // <== note
public class TextFileFormatterWithThrows {
  public static void main(String[] args)
      throws FileNotFoundException {   // <== note
    // Construct a Formatter to write formatted output to a text file
    Formatter out = new Formatter(new File("out.txt"));
    // Write to file with format() method (similar to printf())
    int num1 = 1234;
    double num2 = 55.66;
    String name = "Paul";
    out.format("Hi %s,%n", name);
    out.format("The sum of %d and %.2f is %.2f%n", num1, num2, num1 + num2);
    out.close();                 // Close the file
    System.out.println("Done");  // Print to console
  }
}
 
Run the above program, and check the outputs in text file "out.txt".
/*
 * Output to File.
 * Technique 2: Use try-catch to handle exception
 */
 
import java.io.File;
import java.util.Formatter;           // <== note
import java.io.FileNotFoundException; // <== note

public class TextFileFormatterWithCatch {
   public static void main(String[] args) {
      try {    // try the following statements
         // Construct a Formatter to write formatted output to a text file
         Formatter out = new Formatter(new File("out.txt"));
         // Write to file with format() method (similar to printf())
         int num1 = 1234;
         double num2 = 55.66;
         String name = "Pauline";
         out.format("Hi %s,%n", name);
         out.format("The sum of %d and %.2f is %.2f%n", num1, num2, num1 + num2);
         out.close();                // Close the file
         System.out.println("Done"); // Print to console
      } catch (FileNotFoundException ex) {  // catch the exception here
         ex.printStackTrace();       // Print the stack trace
      }
   }
}

  Input via a Dialog Box

You can also get inputs from users via a graphical dialog box, using the JOptionPane class. For example, the following program prompts the user to enter the radius of a circle, and computes the area.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/*
 * Input via a Dialog box
 */
import javax.swing.JOptionPane;   // Needed to use JOptionPane
public class JOptionPaneTest {
   public static void main(String[] args) {
      String radiusStr;
      double radius, area;
      // Read input String from dialog box
      radiusStr = JOptionPane.showInputDialog("Enter the radius of the circle");
      radius = Double.parseDouble(radiusStr);   // Convert String to double
      area = radius*radius*Math.PI;
      System.out.println("The area is " + area);
   }
}

Dissecting the Program: 

· In Line 4, the import statement is needed to use the JOptionPane.
· In Line 10, we use the method JOptionPane.showInputDialog(promptMessage) to prompt users for an input, which returns the input as a String.
· Line 11 converts the input String to a double, using the method Double.parseDouble().

 java.io.Console (JDK 1.6)
Java SE 6 introduced a new java.io.Console class to simplify character-based input/output to/from the system console. BUT, the Console class does not run under IDE (such as Eclipse/NetBeans)!!!
 
To use the new Console class, you first use System.console() to retrieve the Console object corresponding to the current system console.
 
Console con = System.console();
You can then use methods such as readLine() to read a line. You can optionally include a prompting message with format specifiers (e.g., %d, %s) in the prompting message.
 
String inLine = con.readLine();
String msg = con.readLine("Enter your message: ");       
 // readLine() with prompting message
String msg = con.readLine("%s, enter message: ", name);  
 // Prompting message with format specifier
 
You can use con.printf() for formatted output with format specifiers such as %d, %s. You can also connect the Console to a Scanner for formatted input, i.e., parsing primitives such as int, double, for 
 
example,
Scanner in = new Scanner(con.reader());  // Use Scanner to scan the Console
 
// Use the Scanner's methods such as nextInt(), nextDouble() to parse primitives
 
int anInt = in.nextInt();
double aDouble = in.nextDouble();
String str = in.next();
String line = in.nextLine();
 
Example:
/*
 * Testing java.io.Console class
 */
 
import java.io.Console;
import java.util.Scanner;
public class ConsoleTest {
   public static void main(String[] args) {
      Console con = System.console();   // Retrieve the Console object
      // Console class does not work in Eclipse/NetBeans
      if (con == null) {
          System.err.println("Console Object is not available.");
          System.exit(1);
      }
  
      // Read a line with a prompting message
      String name = con.readLine("Enter your Name: ");
      con.printf("Hello %s%n", name);
      // Use the console with Scanner for parsing primitives
      Scanner in = new Scanner(con.reader());
      con.printf("Enter an integer: ");
      int anInt = in.nextInt();
      con.printf("The integer entered is %d%n", anInt);
      con.printf("Enter a floating point number: ");
      double aDouble = in.nextDouble();
      con.printf("The floating point number entered is %f%n", aDouble);
      in.close();
   }
}
 
The Console class also provides a secure mean for password entry via method readPassword(). This method disables input echoing and keep the password in a char[] instead of a String. The char[] containing the password can be and should be overwritten, removing it from memory as soon as it is no longer needed. (Recall that Strings are immutable and cannot be overwritten. When they are longer needed, they will be garbage-collected at an unknown instance.)
 
/*
 * Inputting password via Console
 */
 
import java.io.Console;
import java.util.Arrays;
public class ConsolePasswordTest {
   static String login;
   static char[] password;
  
   public static void main(String[] args) {
      Console con = System.console();
      if (con == null) {
         System.err.println("Console Object is not available.");
         System.exit(1);
      }
  
      login = con.readLine("Enter your login Name: ");
      password = con.readPassword("Enter your password: ");
      if (checkPassword(login, password)) {
         Arrays.fill(password, ' ');  // Remove password from memory
         // Continue ...
  
      }
   }
  
   static boolean checkPassword(String login, char[] password) {
       return true;
   }
}

No comments:

Post a Comment

Please write your view and suggestion....