Ahmad Fahmy
Ahmad Fahmy

Reputation: 327

Stuck inside while loop

I'm trying to print the value of z as output but My code doesn't finish execution..it reaches the line "here" but never reachs the last line "z is ".

i'm guessing s = sc.nextInt(); is the problem.

public class Solution {

public static void main(String[] args) {

    Scanner sc=new Scanner(System.in);
    int x = 0;
    int y = 0;
    int z = 0;
    int u = 0;
    int n = sc.nextInt();
    int s = sc.nextInt();
    while(sc.hasNextInt()) {
        if(s != -1){
            y = s;
            if(sc.hasNextInt()){
                s = sc.nextInt();                 
            }
        }     
        while(s == -1){
            x++;
            System.out.println("s is "+s);
            z = Math.abs(y - x) + u;
            System.out.println("s is "+s);
            System.out.println("x is " + x+ " y is "+ y+" z is "+z);
            if(sc.hasNextInt()){
                s = sc.nextInt();                 
                System.out.println("s33 is "+s);
            }
        }
        if(z != 0){
            u = z;
        }    
        x = 0;
        y = 0;
        System.out.println("here");
    }
    System.out.println("z is" +z);
    }
}

Thanks.

Upvotes: 2

Views: 639

Answers (2)

thatguy
thatguy

Reputation: 22079

Problem

You are using a Scanner on the system input stream System.in. That means sc.hasNextInt() tries to get the next value from the underlying stream, which is System.in. However, this stream will just prompt you for new input and return it to the Scanner. Once the Scanner receives a newline character, it checks, if the sequence before is an int or not. In case you only hit enter, the sequence is empty, hence ignored. It is not the loop that is indefinitely executed if you hit enter repeatedly, your code is stuck at sc.hasNextInt(), which gets no new token (because of the empty sequence), and asks the underlying stream again and again.

However, if you enter anything but an int, like 0.2 or abc... the Scanner will return false, as the sequence is not empty and not an int.

Solution

If you want to keep your code as it is and you want that hasNextInt() returns false when you hit enter (only newline), you can wrap your Scanner in this wrapper:

import java.util.Scanner;

public class ScannerWrapper {

    private Scanner scanner;
    private Integer current;

    public ScannerWrapper(Scanner scanner) {
        this.scanner = scanner;
    }

    public boolean hasNextInt() {

        // Current is not null, if method is called multiple
        // times, the value was checked already, it is an integer
        if (current != null) {
            return true;
        } else {

            // Reads line including newline character
            String nextLine = scanner.nextLine();

            try {
                // Try to covert the input to an integer
                current = Integer.parseInt(nextLine);
                return true;
            } catch (NumberFormatException e) {
                // Input is not an integer
                return false;
            }

        }
    }

    public int nextInt() {

        // Used the already checked value or request new input
        if (current != null) {
            int next = current;
            current = null;
            return next;
        } else {

            int next = scanner.nextInt();

            // Consume the newline character
            scanner.nextLine();

            return next;

        }
    }

}

This class reads complete lines and converts them into int, if possible. As you cannot push back the last token you have read with a Scanner, this class stores it temporarily, so multiple calls to hasNextInt() do not skip values. In your method just add:

public static void main(String[] args) {

    Scanner scanner = new Scanner(System.in);
    ScannerWrapper sc = new ScannerWrapper(scanner);

    int x = 0;
    // Rest of your code...

}

Upvotes: 0

Rahul Deore
Rahul Deore

Reputation: 37

Its not going in infinite loop but instead you already have two values stored in Scanner which you are checking with hasNextInt(). Hence its always true and waits for next input to check. If you go with entering Int values it will be in same while loop. Enter non-integer like String to go out of while loop and your program will end. Actually You are waiting for input in both while loops and hence its waiting for your input.

Upvotes: 1

Related Questions