Reputation: 33
I'm trying to parse a char from console input using in.nextLine()
and from there take charAt(0)
. My problem is after asking the user to enter a string to perform the in.nextLine()
on, it skips the input and yields an error due to trying to get the first character of a null string.
System.out.print("Select an operator (+, -, *, /), 'c' or 'C' to clear, or 'q' to quit: ");
String temp = in.nextLine();
char tempOperator = temp.charAt(0);
the error is
java.lang.StringIndexOutOfBoundsException: String index out of range: 0
at java.lang.String.charAt(Unknown Source)
full program is available here
General comments and suggestions always welcome. Thanks in advance.
Upvotes: 3
Views: 3840
Reputation: 34367
When you do cValue = in.nextDouble();
, it reads the next token(full value) and parses it to double. If the return key was pressed at this time, \n
is the next token in the buffer to read.
When you do: String temp = in.nextLine();
, it reads the \n
from the buffer of the previous enter and charAt(0)
fails as it has read only empty("") string.
To overcome the issue, either skip the previous buffer by adding an addition in.nextLine()
, add \n \r
as skip pattern as below (this is the pattern defined in Scanner.class
as LINE_SEPARATOR_PATTERN
):
in.skip("\r\n|[\n\r\u2028\u2029\u0085]");
or put a small while
loop as below:
String temp = "";
while((temp.length() < 0){
temp = in.nextLine();
}
Upvotes: 4
Reputation: 213261
Well, the problem is in the line in.nextDouble()
.
Scanner#nextDouble
reads the next token from the user as double. So, when you pass a value 4.5
as input, then the nextDouble
just reads the token 4.5
and skips the linefeed
after that input that user have entered. Now this linefeed(Since this is a new line), will be regarded as input for the next Scanner.nextLine
. And hence your in.nextLine
after in.nextDouble
is reading the newline
left over by the previous in.nextDouble
.
So, the workaround is the same that @tjg184 has pointed out in his answer. Add an empty in.nextLine
after in.nextDouble
that will read that newline
left over. So, that your coming in.nextLine
reads the input actually passed.
cValue = in.nextDouble();
in.nextLine(); // Add this before your `while` which will read your `newline`
while (true) {
//continue;
}
Whereas, Scanner.nextLine
reads the complete input till the newline. So, it will not leave any newline
to be read by the next read by user.
Although this answer was not needed, as the @tjg184's
answer does the same. I just added it to give a better explanation of what exactly is happening.
Upvotes: 1
Reputation: 1904
One thing you might consider is instead of doing this:
String temp = in.nextLine();
Do this:
String temp = in.next();
That of course is assuming that you only want a single character from the user input, which it looks like that is all you are asking the user for. This will get rid of the exception you are receiving. However, you may want to read the whole line first to see what the length is, if you would like to throw an error when the user types more than one character.
Upvotes: 1
Reputation: 4676
Looking at your program, it's because of String temp = in.nextLine();
. When the user hits the "Enter" key, it essentially is skipping this statement since the user typed hit "Enter". Try the following. Note, I only added the following line String enter = in.nextLine();
import java.util.Scanner;
public class Calculator
{
public static void main(String[] args)
{
Scanner in = new Scanner(System.in);
char operator = 'z'; //initialize operator
double cValue; //current value
double rhValue; //right hand value
boolean cont = true;
System.out.print("Enter starting value: ");
cValue = in.nextDouble();
// disregard the "Enter" key
String enter = in.nextLine();
while(true)
{
System.out.print("Select an operator (+, -, *, /), 'c' or 'C' to clear, or 'q' to quit: ");
String temp = in.nextLine();
char tempOperator = temp.charAt(0);
if (tempOperator == 'c' || tempOperator == 'C')
{
cValue = 0.0;
System.out.println("Current value is: " + cValue);
System.out.println();
}
else if(tempOperator == 'q')
{
System.out.println("Final result: " + cValue);
System.exit(1);
}
else if(tempOperator == '+' || tempOperator == '-' || tempOperator == '*' || tempOperator == '/')
{
operator = tempOperator;
break;
}
else
throw new IllegalArgumentException("operator not valid");
}
System.out.println("Enter a right hand value (type double): ");
rhValue = in.nextDouble();
System.out.println("Math expression: answer " + operator + "= " + rhValue);
switch(operator)
{
case '+': cValue =+ rhValue;
break;
case '-': cValue =- rhValue;
break;
case '*': cValue = cValue * rhValue;
break;
case '/': cValue = cValue / rhValue;
break;
}
System.out.println("Current value is: " + cValue);
}
}
Upvotes: 0