1
boolean yn = true;
        while(yn)
        {
            System.out.println("please enter your name");
            char name = (char) System.in.read();
            switch(name)
            {
                case 'y':
                    yn = false;
                    break;
                case 'Y':
                    yn = false;
                    break;
                case 'n':
                    yn = false;
                    break;
                case 'N':
                    yn = false;
                    break;
                default:
                    System.out.println("You did not input a correct choice");
            }

When I enter other keys than y or n, more than one of same output keeps coming out. Any suggestions? I want to see only one output, and System.in.read() is a must. Not scanner.

Atul Dwivedi
  • 1,452
  • 16
  • 29
James Guy
  • 21
  • 3

3 Answers3

2

You're using System.in.read() to read in the next character, but when you type a character and hit enter, you're actually entering three characters: The character you typed, a carriage return character ('\r'), and a newline character ('\n'). I assume you're on a Mac, because Windows machine just use the newline character.

Since you're inside of a while loop, it keeps reading until you hit a valid character that sets yn to true.

You might consider using a Scanner to make this easier.

Jordan
  • 2,273
  • 9
  • 16
  • I think you're right. This is his problem....the newline character(s). I'll just point out, however, that Mac acts just like Linux, and uses only '\n' as EOL. I thought it was just Windows that used '\r\n' for EOLs. - but this only matters in that he might get two extra characters he might not expect rather than 1. – CryptoFool Feb 27 '19 at 02:34
  • I tested locally and saw just '\n' on my Windows machine, so I assumed it was "\r\n" on Linux-based systems. I wonder if it's just an IntelliJ console thing. – Jordan Feb 27 '19 at 02:40
  • It may be that System.in is opened in "character mode", like doing open("xxx", "r") rather than open("xxx", "rb"). In the former case, Java standardizes the stream on all systems to only return '\n'. Only if you're reading in "binary mode" do you possibly get something other than '\n'. The one way I'm pretty sure you get "\r\n" is if you open a Windows file in "rb" mode. - I bet you always get just '\n' from System.in. – CryptoFool Feb 27 '19 at 03:01
0

The reason of infinite loop is you read input from System.in.read() and cast it into char.

System.in.read() will return code -1 when the end of input stream. If you cast it into char the value will be 65535.

So, please add this piece of code after: char name = (char) System.in.read();

System.out.println("name="+name);
char next = (char)System.in.read();
if(next==65535)
    break;

This code works for me. https://ideone.com/ppk3Fi

someone
  • 122
  • 2
  • 9
  • Huh? How does System.in.read() every get to "the end of input stream"? That's relevant for files, but not standard input. – CryptoFool Feb 27 '19 at 02:40
  • @Steve according to [java doc](https://docs.oracle.com/javase/7/docs/api/java/io/InputStream.html#read%28%29) the read() method will return -1 when the end of stream is reached. – someone Feb 27 '19 at 02:51
  • I understand that. But what does "the end of stream is reached" mean for System.in? One does not normally reach EOS for System.in. It provides characters or blocks forever. – CryptoFool Feb 27 '19 at 02:57
  • Oh, I get your point. The input stream will not be empty, so `read()` method must always provide bytes to return. In openJDK implementation, if you did not set `InputStream in System.in`, it will default use BufferedInputStream. The BufferedInputStream override [read](http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/tip/src/share/classes/java/io/BufferedInputStream.java#l263) method, it will return `-1` when the buffer is empty. – someone Feb 27 '19 at 03:33
  • @Steve I would like to know the reason of input stream must not be empty. Could you please give some document to read or any keyword?? – someone Feb 27 '19 at 03:39
0

This is my take on this. Using Scanner class instead.

Scanner scanner = new Scanner (System.in);
System.out.println("please enter your name");
char name = scanner.next().charAt(0);

Mine I would get the first character entered instead.

danielctw
  • 83
  • 6