Flatfoot's blog

By Flatfoot, 11 years ago, In English

Abstract

In the following I will describe how to read the input in Java. We will examine the Scanner class and then write our own class for faster input reading.

Using the Scanner class

We can read the input using the Scanner class:

import java.util.*;
 
public class Main{
   public static void main(String[] args) {
      // Use the Scanner class
      Scanner sc = new Scanner(System.in);  
      /*
      int n      = sc.nextInt();        // read input as integer
      long k     = sc.nextLong();       // read input as long
      double d   = sc.nextDouble();     // read input as double
      String str = sc.next();           // read input as String
      String s   = sc.nextLine();       // read whole line as String
      */
    }
}

Using the BufferedReader class

However, the Scanner class is slow and may cause a "timelimit exceeded". We can read the input faster with the BufferedReader class. The class "MyScanner" below uses a BufferedReader. The same method names as in the Scanner class have been chosen, e.g. to read the input as an integer we still can use nextInt().

import java.io.*;
import java.util.*;
 
 
public class Main{
   public static void main(String[] args) {
      MyScanner sc = new MyScanner();
      out = new PrintWriter(new BufferedOutputStream(System.out));
      
      // Start writing your solution here. -------------------------------------
   
      /*
      int n      = sc.nextInt();        // read input as integer
      long k     = sc.nextLong();       // read input as long
      double d   = sc.nextDouble();     // read input as double
      String str = sc.next();           // read input as String
      String s   = sc.nextLine();       // read whole line as String

      int result = 3*n;
      out.println(result);                    // print via PrintWriter
      */

      // Stop writing your solution here. -------------------------------------
      out.close();
   }

     

   //-----------PrintWriter for faster output---------------------------------
   public static PrintWriter out;
      
   //-----------MyScanner class for faster input----------
   public static class MyScanner {
      BufferedReader br;
      StringTokenizer st;
 
      public MyScanner() {
         br = new BufferedReader(new InputStreamReader(System.in));
      }
 
      String next() {
          while (st == null || !st.hasMoreElements()) {
              try {
                  st = new StringTokenizer(br.readLine());
              } catch (IOException e) {
                  e.printStackTrace();
              }
          }
          return st.nextToken();
      }
 
      int nextInt() {
          return Integer.parseInt(next());
      }
 
      long nextLong() {
          return Long.parseLong(next());
      }
 
      double nextDouble() {
          return Double.parseDouble(next());
      }
 
      String nextLine(){
          String str = "";
	  try {
	     str = br.readLine();
	  } catch (IOException e) {
	     e.printStackTrace();
	  }
	  return str;
      }

   }
   //--------------------------------------------------------
}

References

  1. FastScanner class used by xenoslash.

  2. Faster input for java – An article by James Brucker

  3. ReadLine in Java

If you know of a simpler/better method for input reading in Java, please post it below.

Edit 1 (30 August 2014)

I added PrintWriter for a faster output.

  • Vote: I like it
  • +5
  • Vote: I do not like it

| Write comment?
»
10 years ago, # |
  Vote: I like it -8 Vote: I do not like it

thanks a lot. could you explain the next() function.

i don't understand why while (st == null || !st.hasMoreElements()) especially !st.hasMoreElements() this part.

and how it is working ? like — int a = sc.nextInt(); int b = sc.nextInt();

if i gave input 1 2 then how can this do like a = 1 and b = 2 ? every time i call nextInt() then it call next() in a new form. so how it can split the output and put those in different variable ? thanks in advance.

  • »
    »
    10 years ago, # ^ |
      Vote: I like it 0 Vote: I do not like it

    What is st? It's StringTokenizer. Read its javadocs.

»
10 years ago, # |
  Vote: I like it -6 Vote: I do not like it

Green tutorial? lol

»
9 years ago, # |
  Vote: I like it 0 Vote: I do not like it

great tutorial! Thx a lot for sharing! So are we allowed to use your code for contest? :-)

»
7 years ago, # |
  Vote: I like it 0 Vote: I do not like it

I could not understand the while loop part. Could anyone explain me that?

  • »
    »
    3 years ago, # ^ |
      Vote: I like it +1 Vote: I do not like it

    Sorry for necroposting. But I thought it will be nice to have an explanation as I see 2 people asking for it.

    I know I am late. But this is for anyone else who might not understand it.

          String next() {
              // Do not process the insides of loop if there are tokens(parts of input in line) already present in st object
              // After reading the items from the stream, st will have tokens in it (in a scenario of empty lines, the loop will be executed until there are valid tokens).
              // If there is nothing left in the standard input, the loop will be terminated by an execption thrown by 'br.readLine()'
              while (st == null || !st.hasMoreElements()) {
                  try {
                      // If there are no tokens present, read a new line from input
                      st = new StringTokenizer(br.readLine()); 
                  } catch (IOException e) {
                      e.printStackTrace();
                  }
              }
              // If there were tokens already present in the st object, the while loop will not be executed and we will get the token from the earlier line read from the stream.
              // If there were no tokens present in the st object, they will be populated by the while loop above.
              return st.nextToken(); 
          }
    
    • »
      »
      »
      3 years ago, # ^ |
        Vote: I like it 0 Vote: I do not like it

      String next() throws IOException { while (!in.hasMoreTokens()) { in = new StringTokenizer(br.readLine()); } return in.nextToken(); } i think this one is better

»
6 years ago, # |
  Vote: I like it 0 Vote: I do not like it

Thanks a lot. You save my day.

»
3 years ago, # |
  Vote: I like it 0 Vote: I do not like it

please add for character ??

  • »
    »
    3 years ago, # ^ |
      Vote: I like it 0 Vote: I do not like it

    you can't read char. you can do like this: char c = next().charAt(0);