1

I fail to understand why For loop keeps executing, if condition meet and break statement applied.

Code:

class ProgramControlStatements {
    public static void main(String[] args) throws java.io.IOException {
        System.out.println("Menu: ");
        System.out.println("Choice: ");
        System.out.println("1: If/Else");
        System.out.println("2: Switch");
        for(int i = 0; i < 5; i++) {
            chooseOption();
        };
    };

    static void chooseOption() throws java.io.IOException{
        char choice = (char) System.in.read();
        switch(choice){
            case 'a':
                System.out.println("Computer control statement: If/Else");
                break;
            case 'b':
                System.out.println("Computer control statement: Switch");
                break;
            default:
                System.out.println("No valid option");
        };
    }
}

Expected result:

If char a chosen, print "If/Else" and expect next input until i<5

Computer control statement: If/Else

Actual result:

First Input -> a Computer control statement: If/Else

No valid option

Second input -> b Computer control statement: Switch

No valid option

Third input -> a Computer control statement: If/Else

Program ends.

I expect default statement to be skipped since break statement is applied. Is this happening as System.in.read() returns a new line? I think same behaviour is to be expected from while; do-while loops?

luigi dota
  • 21
  • 3

3 Answers3

3

It's not as easy as @Arvind Kumar Avinash says, depending on your OS you may encounter either a \r (carriage return), \n (new line) or both \r\n after every line.

So just adding another System.in.read() line is a workaround that may not always work.

I suggest using Scanner instead, as suggested here: Take a char input from the Scanner.

LE: As an answer to a request in the comment, I would like to specify that I always try to use Scanner when I want to parse my input and don't mind the performance. When I mind performance, I use BufferedReader. Never System.in directly. You can read more in the answers provided here https://stackoverflow.com/a/21698084/2477456.

Valdrinium
  • 1,305
  • 1
  • 13
  • 25
  • good tip! I've been trying to understand why should I use System.in.read() vs Scanner. I was aware of the Scanner Class, and using it whenever input is needed. Could you point me to a good read on why and when to use System.in.read vs Scanner? – luigi dota Sep 12 '20 at 11:12
  • thank you for the link for end line statements. Should I raise another question for why/when should I use System Class method .in.read vs Scanner Class? – luigi dota Sep 12 '20 at 11:19
  • If you want a more detailed explaination, I think it's a good idea, as I couldn't find one – Valdrinium Sep 12 '20 at 11:20
  • 1
    I will do so, thank you. Will update the link in this chat when I have completed the question. Hai noroc :D – luigi dota Sep 12 '20 at 11:23
1

I believe the answer is a combination between the 2 answers offered so far.

For a quick fix, @Arvind Kumar Avinash is very good.

Looking more in to the problem as @Valdrinium specifies alternatives might be considered.

I am sceptical on choosing @Arvind Kumar Avinash as definitive, although it solve the problem in this instance.

Can an admin help?

luigi dota
  • 21
  • 3
0

It's happening because of the dangling line break character. Just add System.in.read(); once again as shown below to consume dangling line break character e.g. (char) System.in.read() consumes just a but not the Enter character that you press after a.

public class Main {
    public static void main(String[] args) throws java.io.IOException {
        System.out.println("Menu: ");
        System.out.println("Choice: ");
        System.out.println("1: If/Else");
        System.out.println("2: Switch");
        for (int i = 0; i < 5; i++) {
            chooseOption();
        }
    }

    static void chooseOption() throws java.io.IOException {
        char choice = (char) System.in.read();
        System.in.read();// Add this line
        switch (choice) {
        case 'a':
            System.out.println("Computer control statement: If/Else");
            break;
        case 'b':
            System.out.println("Computer control statement: Switch");
            break;
        default:
            System.out.println("No valid option");
        }
    }
}

A sample run:

Menu: 
Choice: 
1: If/Else
2: Switch
a
Computer control statement: If/Else
b
Computer control statement: Switch
a
Computer control statement: If/Else
b
Computer control statement: Switch
a
Computer control statement: If/Else
Arvind Kumar Avinash
  • 50,121
  • 5
  • 26
  • 72