views:

132

answers:

5

here is my program

import java.util.Scanner;
import java.util.Random;

public class Project3
{
    public static void main(String[] args)
    {

        int low;
        int high;
        int answer;
        int guess;
        int numGuess = 0;
        int x;
        int y;

       char repeat; // this will hold y or n 
       String input; //holds input to perform entire loop


        System.out.println( "Hello and welcome to Guess That Number!");

            Scanner keyboard = new Scanner(System.in);

        System.out.println("For starters you get to pick the range the number falls in!" +
                            " HOW EXCITING!");


        System.out.println( "Now what would you like the lowest possible number to be?");
                      low = keyboard.nextInt();

        System.out.println( "and the highest?");
                      high = keyboard.nextInt();
 do  
  {    Random randomNumber = new Random();

        answer = randomNumber.nextInt();
       while (answer < low || answer > high)
       { 
        answer = randomNumber.nextInt();
    }



       guess = -1;

       while(guess != answer)
       {

           System.out.println("What is your guess?");
          System.out.println("Don't forget has to be in between "+ low + " and " + high);

                   guess = keyboard.nextInt();

                   numGuess = (numGuess + 1);

                if (guess < answer)
                {
                    System.out.println("TOO LOW!");

                }

                else if (guess > answer)
                {
                    System.out.println("TOO HIGH!");



                }


            }





       System.out.println("YOU GOT IT WOOOO!");
       System.out.println("The number was " + answer);
       System.out.println("Nice it only took " + numGuess + "!");

       for ( x = 1; x <= numGuess; x++)

      {

          for ( y = 1; y <= answer; y++)

            {
                System.out.print("*");
            }

            System.out.println();



      }


      System.out.println("\nWould you like to play again? \n" +        // this is to loop the entire game
                      "Enter Y for yes or N for no. \n");

                      input = keyboard.nextLine();
                      repeat = input.charAt(0);

  } while (repeat == 'Y' || repeat == 'y');

    if (repeat == 'n' || repeat == 'N')             
    {

    System.out.println("\nThanks for playing! \n");

   }
}
}

when i try and run it it gives me this error message

java.lang.StringIndexOutOfBoundsException: String index out of range: 0 at java.lang.String.charAt(String.java:687)

how do i fix it so the program loops correctly?!?

+2  A: 

before you do this: repeat = input.charAt(0);

check if the string has at-least one character.

deepsat
Not related to the question exactly, but if you enter anything *but* y or n, the program will just exit without saying anything.
mootinator
agreed but before the control can reach the last statement of the program, the code "repeat = input.charAt(0);" is always executed. hence the error. therefore my suggestion above!
deepsat
A: 

IndexOutOfBoundsException means the index you're trying to access of the array does not exist. The exception shows you it's encountering the error at line 687 and it's the String.charAt() method. I'd recommend by taking a closer look at your code around that line. If you're using an IDE, you should try executing in debug with a breakpoint near that line and stepping through the code line by line to watch the variables.

Owen
+1  A: 

First, just a side note, as mootinator stated, your while condition will be false if any input is not 'Y' or 'y', thus exit and the final "\nThanks for playing! \n" will never be displayed. You should revise this construct. Perhaps something like :

boolean playing = true;

while (playing) {
   // play game here

   // ask to play again?

   if (answer == 'N') {
      playing = false;
   }
}

System.out.println("\nThank you for playing!\n");

Now, to address your original problem, you are not checking for empty input. The error is very likely to happen only when you hit enter without entering anything. Another question is then, what to do with empty values? Is it considered to be 'N' or 'Y'? If you consider empty value to be a valid default choice, you should indicate it in your displayed question. Something like:

System.out.print("\nWould you like to play again?\n" + 
                 "Enter Yes or No (default Yes) : ");
do {
   input = keyboard.nextLine().toUpperCase();  // 'Y' == 'y';
   if (input.length() == 0) {  // if the input is empty, we default the value
      repeat = 'Y';     // default value, change this to 'N' if default is No
   } else {
      repeat = input.charAt(0);
      if (repeat != 'N' && repeat != 'Y') {
         System.out.print("Ooops! Please enter Yes or No :");
         repeat = '\0';
      }
   }
} while (repeat == '\0');
// At this point, repeat is either 'Y' or 'N' only, so no need to check for lowercase

If you don't want a default value, simply change the construct to

System.out.print("\nWould you like to play again?\n" + 
                 "Enter Yes or No : ");
do {
   input = keyboard.nextLine().toUpperCase();  // 'Y' == 'y';
   if (input.length() == 0) {  // if the input is empty...
      repeat = '\0';     // null character for empty value
   } else {
      repeat = input.charAt(0);
   }
   if (repeat != 'N' && repeat != 'Y') {
      System.out.print("Ooops! Please enter Yes or No :");
      repeat = '\0';     // make sure the character is null so we don't exit the loop yet
   }
} while (repeat == '\0');
// At this point, repeat is either 'Y' or 'N' only, so no need to check for lowercase
Yanick Rochon
A: 

Instead of this:

repeat = input.charAt(0);

Do this:

try
{
    repeat = input.charAt(0);
}
catch (java.lang.StringIndexOutOfBoundsException exception)
{
//Solve the problem
}

This way you can catch your exception and handle it. EDIT: It's better to learn a little Exception handling in Java in your first lesson, because it's not complicated and will be useful at later, more difficult tasks.

Lajos Arpad
I would really appreciate if I knew what's wrong in my answer from the downvoter's point of view.
Lajos Arpad
Not sure, but it seems that this is because you are suggesting to catch a `RuntimeException`, which is not really a good practice. However, that indeed can fix the problem in hand. But its still a bad idea, especially in this case. The question is why let the exception occur, when you can avoid that altogether in the first place.
Adeel Ansari
We can't solve the problem as he wants, because he didn't specify how he wants to solve the problem, so we need a general solution prototype, which can either be preventing the exception from occuring or catching it. I disagree with the statement that catching runtime exceptions is a bad practice, because in many cases it's the only solution and, the student who asked the question should learn about exception handling too.
Lajos Arpad
I just want it to loop the program back to picking a new number then having the user guess it again with the max and min still preset. the way it is written should work I did what they showed to do in this java textbook and I've already used this format in a different program and it runs fine. I just didn't know why this time around it's not working.
MrRogers04
@Lajos Arpad: Show me the example where catching `RuntimeException` is the only solution. I mean, c'mon, learn to appreciate people advices. Remember, the chap gave you negative and didn't bother to make any comments. Here I am suggesting you the possible reason for that -ve, and you are denying it. First you stated that the questioner never mentioned how he want to solve the problem, then you are suggesting him to learn Exception Handling. Where did he stated he want to learn Exception Handling, BTW? My suggestion to you is, stop arguing irrationally and try to learn from your mistakes.
Adeel Ansari
You can learn the source of the error by paying attention to the error message. You'll always see where the error occured and what was the cause. StringIndexOutOfBoundsException is an Exception which was thrown at runtime, because you didn't handle the situation which accured. That's not a big problem when you have enough experience to determine where can be errors and how to deal with them. Until then, when you get an error message like this, just google the Exception type, in this case StringIndexOutOfBoundsException and in the description of the class you can see potential causes.
Lajos Arpad
"I mean, c'mon, learn to appreciate people advices." Thank you for your advices, as you said, he didn't ask for a solution with Exception handling, but I think I have the right to suggest to learn those. I'm not denying anything, my friend, I don't care for upvotes and downvotes, I just want to help people, but I don't really understand why we are talking about me instead of the question.
Lajos Arpad
My advice to you is to not get personal when you're talking about irrationality, because that's paradoxical. Getting personal is one of the most irrational actions when talking about disagreement and calling others irrational in the same time is just funny.
Lajos Arpad
In my opinion when you think that the other person wrote something wrong, you just downvote him/her and leaving a comment. I always appreciate downvotes with comments, but I'm not appreciating when anybody becomes rude and gets personal. When someone gets personal, that's the sign that the person runs out of arguments and replaces them with rudeness.
Lajos Arpad
@Adeel Ansari: There is no need to get personal, getting personal, it's never leading to good results. As you asked, I'll show you an example where catching runtime exceptions is the only solution. If you're using more threads in your program, you'll encounter runtime exceptions no matter how hard you're trying to prevent them. Of course, there are multithreaded projects where runtime exceptions won't occur, but I'm sure you'll be really surprised when you see that after checking whether your variable is null and it was not null, the other thread changed its value to null.
Lajos Arpad
But, of course, I'm just being "irrational" when I teach you about runtime errors at multithreading.
Lajos Arpad
+1  A: 

It seems that the user is pressing return/enter without inputing Y or N.

Here is the suggestion. No doubt that the code can be made better in many ways, but this is just a suggestion for this very issue. Get rid of the repeat variable completely, and replace respective lines with these.

do {
    .....

} while ("y".equalsIgnoreCase(input));

if (!"y".equalsIgnoreCase(input)) {
  System.out.println("\nThanks for playing! \n");
}
Adeel Ansari