Java: Read input without knowing number of input lines

Viewed 6390

This might be very very basic or may be something I am totally missing. I have started doing some competitive programming on online channels. I have to read comma separated strings and do some manipulations around it but the problem is that I do not know the number of lines of input. Below is the input example

Input 1

John,Jacob
Lesley,Lewis
Remo,Tina
Brute,Force

Input 2

Hello,World
Java,Coder
........
........
//more input lines
Alex,Raley
Michael,Ryan

I am trying to read input and breaking when end of the line is encountered but with no luck. This is what I have been trying

//1st method
Scanner in = new Scanner(System.in);

do{
    String relation = in.nextLine();
    //do some manipulation
    System.out.println(relation);

}while(in.nextLine().equals(""));   //reads only first line and breaks

//2nd method
Scanner in = new Scanner(System.in);
while(in.hasNext()){
    String relation = in.next();
    System.out.println(relation);
    if(relation.equals("")){
        break;
    }
}

//3rd method
Scanner in = new Scanner(System.in);
while(true){   //infinite loop
    String relation = in.nextLine();
    System.out.println(relation);
    if(relation.equals("")){
        break;
    }
}

Can somebody help here.

PS: Please don't judge. I am new to competitive programming though I know how to take user input in java and difference between next() and nextLine().

4 Answers

Im not gonna write why you shouldn't use Scanner. There are numerous articles why you shouldn't use Scanner in competitive programming. Instead use BufferedReader.

In competitive programming they redirect the input to your code from file.

It works like ./a.out > output.txt < input.txt for example.

So read until null is detected in the while loop.

public static void main(String args[] ) throws Exception {

        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        String s;
        while((s = br.readLine()) != null)
        {
            //System.out.println(s);
        }
    }

For testing through your keyboard, to simulate a null from your keyboard:

Press Ctrl+D. It will break out of the while loop above.

It should be fairly easy. Try

while(in.hasNextLine()){
    String relation = in.nextLine();
    if("exit".equalsIgnoreCase(relation))break;
    //do some manipulation
    System.out.println(relation);    
}

The method Scanner#hasNextLine simply checks if there is a next line in the input, doesn't really advance the scanner. On the other hand, Scanner#nextLine reads the input as well as advances the scanner.

Update you might want to put some condition to exit the loop. E.g. the above snippet stops reading more input after it encounters a string "exit".

All your methods can be improved.

But let's consider your second method of while loop.

Scanner in = new Scanner(System.in);
    String s;

    while(in.hasNext()){
        s=in.nextLine();
        System.out.println(s);
       
    }

In the same way, you can change each of your codes. Also you can use BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); to buffer your input then check for in.readLine()) != null

Other than the above two methods (Buffered Reader method & Scanner method), I have another method for solving this issue. Have a look at the following code, you can catch NoSuchElementException to solve this issue , though I didn't recommended this as Exception handling is a costly process .

Out of all the methods, the Buffered should only be used during Competitive Coding as it has the least Complexity.

import java.util.*;

public class Program
{
    public static void main(String[] args) 
    {
        Scanner sc = new Scanner(System.in);


        try   
        {
            while(true)
             String    a=sc.next();
            System.out.print(a);

        }
        catch(NoSuchElementException  k)
        {
        }


    }
}
Related