d2jsp
Log InRegister
d2jsp Forums > Off-Topic > Computers & IT > Programming & Development > Need Help With Basic Java Assignment > Loops N What Not
Prev12
Add Reply New Topic New Poll
Member
Posts: 17,596
Joined: Aug 26 2005
Gold: 20,600.00
Nov 5 2014 07:18pm
Quote (Aimed_Shot @ Nov 5 2014 07:09pm)
not sure what you mean


When I run it, it doesn't run the
Code
again = keyboard.nextLine();
when it asks for the bet amount.
Member
Posts: 23,862
Joined: Aug 16 2006
Gold: 20.00
Nov 5 2014 07:33pm
Quote (J-dawg @ Nov 5 2014 08:18pm)
When I run it, it doesn't run the
Code
again = keyboard.nextLine();
when it asks for the bet amount.


there must be something in the buffer after one of your previous reads. It is using that as the value of nextLine();
Member
Posts: 17,596
Joined: Aug 26 2005
Gold: 20,600.00
Nov 5 2014 07:52pm
Quote (Eep @ Nov 5 2014 07:33pm)
there must be something in the buffer after one of your previous reads. It is using that as the value of nextLine();


right now my only other input is
Code
System.out.println("Enter your bet:");
bet = keyboard.nextInt();


How would I go about making it not read the previous input from that?
Member
Posts: 1,995
Joined: Jun 28 2006
Gold: 7.41
Nov 5 2014 08:17pm
Quote (J-dawg @ Nov 5 2014 08:52pm)
right now my only other input is
Code
System.out.println("Enter your bet:");
  bet = keyboard.nextInt();


How would I go about making it not read the previous input from that?


Your Scanner is wrapping whats known as an InputStream. The source of the InputStream is the console (System.in). That input stream will continue to accumulate and buffer data as long as you continue to enter it. When you invoke any of the next methods on the Scanner object, you are only removing whatever you asked for from that buffer. Everything else remains. In the case of nextInt(), it removes the next integer value within the stream.

So let's look at what you entered into the stream.

If you wanted to bet 100, you executed the following keystroke sequence 1 0 0 Enter. Now, you think you only buffered the value 100 into the stream, but that Enter resolves to a character value. On a Windows machine it will be a single newline character "\n", which represents a carriage return and a newline. On other OS's an Enter will actually result in 2 characters being added to the stream, a \r and a \n, because \n doesn't include the \r like it does in Windows.

But assuming you are on Windows, now your InputStream has buffered "100\n", so when you do your Scanner.nextInt() it will read the next integer from the buffer, or stop execution and wait for an input if none exists. So, after the nextInt() is completed, whats in the buffer for that InputStream? That's right, now the buffer contains "\n".

So what happens when you then do your again = keyboard.nextLine() statement? Well, nextLine() reads all character from the stream until it encounters a newline character, and returns that as your line. But there is already a new line in your buffer, which is the residual \n from your last input. So it doesn't need to wait for another line to be entered, it will just do that. So it reads that newline character as a line and returns the empty string to again.

So, how do you get around this? Well, there are two ways.

The first would be to do a flush on the Scanner to get rid of the newline. You can do this by calling keyboard.next() or keyboard.nextLine() after you do your keyboard.int(). This would flush that character, but at the cost of binding your implementation to manual console input. What if you wanted to redirect input from a file. Well now you have to put each number on a separate line to ensure there will be a newline character after each int. This might not be an issue, but I find it ugly.

My preferred solution is to do away with nextInt (as well as nextDouble, nextFloat, nextLong, etc), and instead just use nextLine() to read the value as a string and call the respective parse method for that value type.

Code

String s = keyboard.nextLine();
int i = Integer.parseInt(s);

s = keyboard.nextLine();
long l = Long.parseLong(s);

s = keyboard.nextLine();
double d = Double.parseDouble(s);
Member
Posts: 13,425
Joined: Sep 29 2007
Gold: 0.00
Warn: 20%
Nov 5 2014 08:36pm
I said this I said this I really Said this.

Member
Posts: 17,596
Joined: Aug 26 2005
Gold: 20,600.00
Nov 5 2014 08:43pm
Quote (Minkomonster @ Nov 5 2014 08:17pm)
Your Scanner is wrapping whats known as an InputStream. The source of the InputStream is the console (System.in). That input stream will continue to accumulate and buffer data as long as you continue to enter it. When you invoke any of the next methods on the Scanner object, you are only removing whatever you asked for from that buffer. Everything else remains. In the case of nextInt(), it removes the next integer value within the stream.

So let's look at what you entered into the stream.

If you wanted to bet 100, you executed the following keystroke sequence 1 0 0 Enter. Now, you think you only buffered the value 100 into the stream, but that Enter resolves to a character value. On a Windows machine it will be a single newline character "\n", which represents a carriage return and a newline. On other OS's an Enter will actually result in 2 characters being added to the stream, a \r and a \n, because \n doesn't include the \r like it does in Windows.

But assuming you are on Windows, now your InputStream has buffered "100\n", so when you do your Scanner.nextInt() it will read the next integer from the buffer, or stop execution and wait for an input if none exists. So, after the nextInt() is completed, whats in the buffer for that InputStream? That's right, now the buffer contains "\n".

So what happens when you then do your again = keyboard.nextLine() statement? Well, nextLine() reads all character from the stream until it encounters a newline character, and returns that as your line. But there is already a new line in your buffer, which is the residual \n from your last input. So it doesn't need to wait for another line to be entered, it will just do that. So it reads that newline character as a line and returns the empty string to again.

So, how do you get around this? Well, there are two ways.

The first would be to do a flush on the Scanner to get rid of the newline. You can do this by calling keyboard.next()  or keyboard.nextLine() after you do your keyboard.int(). This would flush that character, but at the cost of binding your implementation to manual console input. What if you wanted to redirect input from a file. Well now you have to put each number on a separate line to ensure there will be a newline character after each int. This might not be an issue, but I find it ugly.

My preferred solution is to do away with nextInt (as well as nextDouble, nextFloat, nextLong, etc), and instead just use nextLine() to read the value as a string and call the respective parse method for that value type.

Code
String s = keyboard.nextLine();
int i = Integer.parseInt(s);

s = keyboard.nextLine();
long l = Long.parseLong(s);

s = keyboard.nextLine();
double d = Double.parseDouble(s);


Thank you very much
Member
Posts: 23,862
Joined: Aug 16 2006
Gold: 20.00
Nov 5 2014 10:11pm
I worded my response poorly, thankfully minko was there with the knowledge

hope you get it working
Go Back To Programming & Development Topic List
Prev12
Add Reply New Topic New Poll