StringIndexOutOFBoundsException: 0 - java

I am a relative beginner to Java and am having an issue with a user controlled do-while loop that accepts user input to repeat. Here is the code at the end of the loop.
System.out.print("Do you wish to continue? (Y for yes " +
"/ N for no)");
input = keyboard.nextLine();
input.length();
repeat = input.charAt(0);
}while (repeat == 'Y' | repeat == 'y');
I know it's throwing the exception because of the value, but can't figure out what to do to fix it, as I'm sure it's relatively simple. Thanks for the help.
Edit 1:
Stacktrace:
Exception in thread "main" java.lang.StringIndexOutOfBoundsException:
String index out of range: 0
at java.lang.String.charAt(Unknown Source)
at FractionTest.main(FractionTest.java:59)

It looks like you read empty line which returned you empty string "" so there is no characters there (not even 0th).
It usually happens when you are using nextLine right after other nextABC methods like nextInt since such methods doesn't consume line separators, and nextLine reads text until next line separator (or end of stream).
In that case you can add nextLine after that nextInt to consume line separator.
Anyway to avoid reading character from empty string and exception you can use something like
} while (input.toLowerCase().startsWith("y"));
instead of
input.length();//this actually doesn't change anything, you can remove it
repeat = input.charAt(0);
} while (repeat == 'Y' | repeat == 'y');

As #Phesmo mentioned you may be getting a 0-length line. This is an obscure problem. Have you called nextInt(), nextLong(), nextShort(), nextByte(), or nextBoolean() on the Scanner before calling nextLine()?
Try this
System.out.print("Do you wish to continue? (Y for yes / N for no)");
char ans;
do {
ans = keyboard.next().charAt(0);
// filter input
} while (ans == 'Y' || ans == 'y' || ans == 'N' || ans == 'n');
repeat = ans;
} while (repeat == 'Y' | repeat == 'y');
From documentation:
String Scanner#next()
Finds and returns the next complete token from this scanner. A complete token is preceded and followed by input that matches the delimiter pattern.
Or this
System.out.print("Do you wish to continue? (Y for yes / N for no)");
repeat = keyboard.next("[YyNn]").charAt(0);
} while (repeat == 'Y' | repeat == 'y');
From documentation:
String Scanner#next(String pattern)
Returns the next token if it matches the pattern constructed from the specified string.
"[YyNn]" is a character class pattern, it means match any character from the set.

Related

How to make do-loop conditions "when string does not equal"

I want to make my do loop run while the input the user made is not equal to the required letters (a-i) For some reason,even when i input the proper letters, it loops forever.
I've tried using switch cases as well as != inside the comparison.
Here is my code:
do {
System.out.println("Please enter the location of your battleship, starting with the first letter value. Make sure it is from the letters a-i.");
lL1=in.nextLine();
if (!lL1.equals("a")||!lL1.equals("b")||!lL1.equals("c")||!lL1.equals("d")||!lL1.equals("e")||!lL1.equals("f")||!lL1.equals("g")||!lL1.equals("h")||!lL1.equals("i")){
System.out.println("Invalid Input. Try again.");
}//End if statement
}while(!lL1.equals("a") || !lL1.equals("b") || !lL1.equals("c") || !lL1.equals("d") || !lL1.equals("e") || !lL1.equals("f") || !lL1.equals("g") || !lL1.equals("h") || !lL1.equals("i"));
My skills in Java are limited but this should work, unless i'm missing something obvious. Any help would be amazing!
Instead of using an operator for each case of the input, you might want to create a list of the accepted answers and then your condition will look like:
while answer is not in accepted answers, ask another input
An example would be:
Scanner scanner = new Scanner(System.in);
List<String> acceptedAnswers = Arrays.asList("a", "b", "c", "d", "e", "f", "g", "h", "i");
String input;
do {
System.out.println(
"Please enter the location of your battleship, starting with the first letter value. Make sure it is from the letters a-i.");
input = scanner.nextLine();
} while (!acceptedAnswers.contains(input));
scanner.close();
System.out.println("Got correct input: " + input);
If you have a negation you need AND to join the conditions not OR.
That's because if you or some not-ed values, they form an and.
Let me explain better.
If you input a, then the first is false (because you not it), and the others are true, so the or condition make the result be true.
You should instead group all the ors and then not it.
e.g.
!(lL1.equals("a") || lL1.equals("b") || lL1.equals("c") || lL1.equals("d") || lL1.equals("e") || lL1.equals("f") || lL1.equals("g") || lL1.equals("h") || lL1.equals("i"))
Please try this:
char lL1;
Scanner scanner = new Scanner(System.in);
do {
System.out.println("Please enter the location of your battleship, starting with the first letter value. Make sure it is from the letters a-i.");
lL1=scanner.next().charAt(0);
}while(lL1!='a' && lL1!='b' && lL1!='c' && lL1!='d' && lL1!='e' && lL1!='f' && lL1!='g' && lL1!='h' && lL1!='i');
Since you are only getting a single character, you can check that it does not match either [a to i] characters as shown above. This is the shortest way to do so by making the check as the condition of the loop. If it fails then the loop will be called.

Why does this While loop cycle twice?

I made this while loop that is supposed to fulfill functions for different shapes and after it fulfills the function for that shape, it will keep asking for shapes until the user types "Exit". I have only done Triangles so far so I just have some filler functions to fulfill to make sure that it loops correctly. The problem is, after I'm done with triangles, it will print the menu twice before asking for an input instead of just printing once. Can anyone explain this to me?
while(password){
System.out.println();
System.out.println("---Welcome to the Shape Machine---");
System.out.println("Available Options:");
System.out.println("Circles");
System.out.println("Rectangles");
System.out.println("Triangles");
System.out.println("Exit");
String option = keyboard.nextLine();
if(option.equals("Exit")){
System.out.println("Terminating the program. Have a nice day!");
return;
} else if(option.equals("Triangles")){
System.out.println("Triangles selected. Please enter the 3 sides:");
int sideA = 0;
int sideB = 0;
int sideC = 0;
do{
sideA = keyboard.nextInt();
sideB = keyboard.nextInt();
sideC = keyboard.nextInt();
if(sideA<0 || sideB<0 || sideC<0)
System.out.println("#ERROR Negative input. Please input the 3 sides again.");
} while(sideA<0 || sideB<0 || sideC<0);
if((sideA+sideB)<=sideC || (sideB+sideC)<=sideA || (sideA+sideC)<=sideB){
System.out.println("#ERROR Triangle is not valid. Returning to menu.");
continue;
} else {
System.out.println("good job!");
}
}
}
It might be that you are using keyboard.nextLine();. In your code outside the while loop make sure that you are always using .nextLine() and nothing else.
Reasoning: If you use .next(), it'll only consume one word so the next time you call .nextLine(), it'll consume the end of that line.
After you say sideC = keyboard.nextInt() the carriage return that you typed (after typing the number) is still in the input buffer. Then you print the menu and execute String option = keyboard.nextLine(); That command reads up to and including the first newline it finds, which is the newline that is still in the buffer.
So option is now a bare newline character, which does not match "Exit" or "Triangle", so it loops again and prints th menu again.
This problem is caused by left-over characters like space, carriage-return, newline, form-feed in the input buffer.
Since the next keyboard.nextLine() doesn't match any of given options (and since there is no "else" at the bottom of while loop to deal with this case), the control goes into next iteration, prints the options again. Based on surrounding context of processing of input, there are several good answers to address this problem on SO.
Since your intention is to skip over all blanks, carriage-returns, newlines, form-feeds till you get a valid string (option) again, the following code works best in a case like yours.
System.out.println();
System.out.println("---Welcome to the Shape Machine---");
//...
System.out.println("Exit");
String option = keyboard.nextLine();
keyboard.skip("[\\s]*");

How would you validate multiple data in a while loop?

so I am using a while loop to check if the string entered by a user is an empty string, and if it is it results in an error, and then asks a question again and if it is valid does not repeat. I got this, but how would I also check for a string longer then 60 characers that does the same as as the empty string and also check to see if the string ends in a question mark. As in how would I implement the multiple checks within the loop
while ( x.length() == 0||x.length >100){
System.out.println("empty string not allowed .");
System.out.print( "ask another question: " );
x = scan.nextLine();
}
So I have a loop which checks multiple conditions where I have the error message for empty string and this prints out if the string entered is empty, greater than 100 characters, or doesn't end in question mark. it will continue through until a valid question is input. How would I implement the error messages for just if the empty string is entered or a string that is greater than 100 or a string that doesnt end with a question mark
you can use 'or' in the condition checking.
while ( x.length() == 0 || x.length<60 || [Any other condition comes here]){
System.out.println("empty string not allowed .");
System.out.print( "ask another question: " );
x = scan.nextLine();
Hope this answers your question.
This should solve your purpose
while( x.trim().length()==0 || x.length()>60 || !x.endsWith("?")
||(x.length().trim()==1 && x.endsWith("?")) ) {
System.out.println("empty string not allowed .");
System.out.print( "ask another question: " );
x = scan.nextLine();
}
The last condition is to check if the user just enters a "?", then loop again so as to make him ask a question with content. So in effect this loops runs if :
The user enters empty string
The user enters more than 60 characters
The user does not end the question with '?'
The user just enters '?' without any content

How do I avoid StringIndexOutOfBoundsException when char has no value?

Sorry if the title made no sense but I did not know how to word it.
The problem:
I'm making a multiple choice quiz game that gets either a, b, c or d from the user. This is no problem if they do as they are told, however if they don't type anything and just hit enter I get a StringIndexOutOfBoundsException. I understand why this is happening, but I'm new to Java and can't think of a way to fix it.
What I have so far:
System.out.println("Enter the Answer.");
response = input.nextLine().charAt(0);
if(response == 'a')
{
System.out.println("Correct");
}
else if(response == 'b' || response == 'c' || response == 'd')
{
System.out.println("Wrong");
}
else
{
System.out.println("Invalid");
}
Of course the program will never make it past the second line of code if the user types nothing, because you can't take the charAt(0) value of an empty String. What I'm looking for is something that will check if the response is null, and if so ask go back and ask the question to the user again.
Thanks in advance for any answers.
You can use a do-while loop. Just replace
response = input.nextLine().charAt(0);
with
String line;
do {
line = input.nextLine();
} while (line.length() < 1);
response = line.charAt(0);
This will continue to call input.nextLine() as many times as the user enters a blank line, but as soon as they enter a non-blank line it will continue and set response equal to the first character of that non-blank line. If you want to re-prompt the user for the answer, then you could add the prompt to the inside of the loop. If you want to check that the user entered a letter a–d you could also add that logic to the loop condition.
Either handle the exception(StringIndexOutOfBoundsException) or break this statement
response = input.nextLine().charAt(0);
as
String line = input.nextLine();
if(line.length()>0){
response = line.charAt(0);
}
Exception Handling:
try{
response = input.nextLine().charAt(0);
}catch(StringIndexOutOfBoundsException siobe){
System.out.println("invalid input");
}
Simple:
Get the input initially as a String, and put it into a temporary String variable.
Then check the String's length.
then if > 0 extract the first char and use it.
In addition #HovercraftFullOfEels' (perfectly valid) answer, I'd like to point out that you can "catch" these exceptions. For example:
try {
response = input.nextLine().charAt(0);
} catch (StringIndexOutOfBoundsException e) {
System.out.println("You didn't enter a valid input!");
// or do anything else to hander invalid input
}
i.e. if a StringIndexOutOfBoundsException is encountered when executing the try-block, the code in the catch-block will be executed. You can read more about catching and handling exceptions here.
StringIndexOutofBoundException will occur in the following situation also.
Searching a string which is not available
Match with the string which is not available
for ex:
List ans=new ArrayList();
temp="and";
String arr[]={"android","jellybean","kitkat","ax"};
for(int index=0;index < arr.length;index++ )
if(temp.length()<=arr[index].length())
if(temp.equlsIgnoreCase((String)arr[``index].subSequence(0,temp.length())));
ans.add(arr[index]);
the following code is required to avoid indexoutofboundexception
if(temp.length()<=arr[index].length())
because here we are cheking the length of src string is equal or greater than temp .
if the src string length is less than it will through "arrayindexoutof boundexception"

Can't get charAt(0) to work

Ok, so I can't seem to get this to work, though many people have told me the syntax and logic is correct. Can anyone reveal for me what I could possibly be doing wrong?
public Scanner in = new Scanner(System.in);
public void movePlayer() {
System.out.print("move: ");
String str = in.nextLine();
in.nextLine();
char c = str.charAt(0);
if (c == 'l' || c == 'L') {
player.moveLeft();
}
}
The program gets caught at char c = str.charAt(0);
And I am being returned this error:
java.lang.StringIndexOutOfBoundsException:
String index out of range: 0 (in java.lang.String)
you did not input anything though the console, so str is empty. this is the reason why chatAt(0) throw an exception
You don't want to use nextLine(). You want to use next().
String str = in.next();
This is the Javadoc for nextLine()
Advances this scanner past the current line and returns the input that was skipped. This method returns the rest of the current line, excluding any line separator at the end. The position is set to the beginning of the next line.
You want next() instead:
Finds and returns the next complete token from this scanner. A complete token is preceded and followed by input that matches the delimiter pattern. This method may block while waiting for input to scan, even if a previous invocation of hasNext() returned true.
This will stop you from consuming the empty line and raising an exception.
This means that str is empty. You should check if it is not null and not empty.
if (str != null && !str.isEmpty()) {
...
}
Add a check for Empty String and Null as well . You will avoid a lot of headaches.
If you press Enter key in console, Scanner will be considered a complete line, regardless of whether or not there is text entered.
Press Enter at the beginning of a line, returns a String "" to the method Scanner.nextLine().
Add a check with str.lenght () > 0 before str.charAt(0).
Use in.next() instead. For whatever reason, nextLine() doesn't work with CharAt() sometimes.

Categories