Results 1 to 13 of 13
  1. #1
    Join Date
    Apr 2011
    Posts
    5
    Rep Power
    0

    Default Out of Bounds Array...sometimes

    Yes, I am a student but this assignment has already been turned in and approved. I never received an answer of why this error happens so I'll turn to the internet. I'm getting an Out of Bounds Array exception and generally I can handle them but this time it only happens half of the time.
    Java Code:
    		//get lottocash balls
    		for(int i=0; i < (ball.length - 1); i++)
    		{
    			System.out.println("Please enter number for LottoCash Ball " + (i+1) + ": ");
    			ball[i] = scan.nextInt();
    
    [B]			if(ball[i] < 1) //make sure input is positive
    			{
    				System.out.println("Number must be greater than 0");
    				i--;
    			}[/B]
    			if(ball[i] > 33) //make sure input is within max boundry
    			{
    				System.out.println("Number must be less than 34");
    				i--;
    			}
    
    		}//end for
    When the user enters a number less than one I get a error that will shut the code down but if they enter something above 31 it just lower the index of the for loop and continues on without any troubles. This idea is copied from a lab we've done from the book.

    Here's the error exactly:
    Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: -1
    at CashBall.readInput(CashBall.java: 49)
    at CashBallTest.main(CashBallTest.java: 6) <- that's the line I call readInput
    Here's the full code for those of you who like to read it all.

    Java Code:
    // I tried to include as many comments as possible
    // to help you understand my thought process better
    
    import java.util.Scanner;
    
    public class CashBall
    {
    	private int[] ball = new int[5]; //array for cashballs
    	private int[] kicker = new int[5]; //array for kicker
    	private int choice = 1; //decision maker
    
    	public CashBall()
    	{
    		for(int i=0; i < ball.length; i++)
    		{
    			ball[i] = 0;
    		}
    		for(int i=0; i < kicker.length; i++)
    		{
    			kicker[i] = 0;
    		}
    	}
    
    	public void readInput()
    	{
    		//display title and describe program
    		System.out.println("\t\t\t\tCashLotto Ball");
    		System.out.println("Player picks four numbers from 1 to 33 called LottoCash Balls.");
    		System.out.println("LottoCash Ball numbers must be unique from all other LottoCash Balls.");
    		System.out.println();
    		System.out.println("The player must also pick out a Cash Ball from 1 to 31");
    		System.out.println();
    		System.out.println("Kicker is a brand new feature you can purchase with your CashBall\nticket which lets you get in on an extra drawing.");
    		System.out.println();
    
    		Scanner scan = new Scanner(System.in);
    
    		//get lottocash balls
    		for(int i=0; i < (ball.length - 1); i++)
    		{
    			System.out.println("Please enter number for LottoCash Ball " + (i+1) + ": ");
    			ball[i] = scan.nextInt();
    
    			if(ball[i] < 1) //make sure input is positive
    			{
    				System.out.println("Number must be greater than 0");
    				i--;
    			}
    			if(ball[i] > 33) //make sure input is within max boundry
    			{
    				System.out.println("Number must be less than 34");
    				i--;
    			}
    
    		}//end for
    
    
    		//get cashball
    		do
    		{
    			System.out.println("Please enter number for the Cash Ball (1-31): ");
    			ball[4] = scan.nextInt();
    
    			if(ball[4] < 1)//message if number is too low
    			{
    				System.out.println("Number must greater than zero");
    			}
    			if(ball[4] > 31)//number if message is too high
    			{
    				System.out.println("Number must be less than 32");
    			}
    		}while(ball[4] < 1 || ball[4] > 31);//end do-while
    
    
    		//get kicker
    		do
    		{
    			System.out.println("Would you like a kicker? (1=yes/2=no)\nThe first four numbers are from a separate set of 0-9\nand the fifth is from a set of 0-4. ");
    			choice = scan.nextInt();
    
    			if(choice == 1)
    			{
    				for(int i=0; i< (kicker.length - 1); i++)
    				{
    					kicker[i] = (int)(Math.random() * 9);
    				}
    				kicker[4] = (int)(Math.random() * 4);
    			}
    
    			if(choice < 1 || choice > 2)
    			{
    				System.out.println("Please select 1 for yes or 2 for no");
    			}
    
    		}while(choice < 1 || choice > 2);//end do-while
    
    	}//end readInput
    
    	public void writeOutput()
    	{
    		if(choice == 1)
    		{
    			System.out.println("Your kicker numbers are: " + kicker[0] + " " + kicker[1] + " " + kicker[2] + " " + kicker[3] + " " + kicker[4]);
    		}
    		else if(choice == 2)
    		{
    			System.out.println("No kicker desired.");
    		}
    		System.out.println("CashLotto numbers are: " + ball[0] + " " + ball[1] + " " + ball[2] + " " + ball[3] + " Cash Ball: " + ball[4]);
    		System.out.println();
    		System.out.println("Good luck with your picks!");
    		System.out.println();
    	}//end writeOutput
    
    	//accessor and mutators
    	public void setCashBall(int index, int num)
    	{
    		ball[index] = num;
    	}
    	public int getCashBall(int index)
    	{
    		return ball[index];
    	}
    	public void setKicker(int index, int num)
    	{
    		kicker[index] = num;
    	}
    	public int getKicker(int index)
    	{
    		return kicker[index];
    	}
    	//end accessor and mutator
    
    }
    The only other class just creates an object of that class and calls readInput and writeOutput. Nothing special.

    I hope this isn't a confusing post. Let me know if you have any questions.

  2. #2
    pbrockway2 is offline Moderator
    Join Date
    Feb 2009
    Location
    New Zealand
    Posts
    4,565
    Rep Power
    12

    Default

    The out of bounds exception says that the bad index value is -1. So you have to ask yourself "how can that be when the loop clearly begins at i=0 and increments?"

    --------------

    Have you looked at "break" and "continue" used with loops? [Edit] and consider different types of loop. Basically you are trying to set values while the index is less than ball.length-1.
    Last edited by pbrockway2; 04-21-2011 at 02:36 AM.

  3. #3
    sunde887's Avatar
    sunde887 is offline Moderator
    Join Date
    Jan 2011
    Location
    Richmond, Virginia
    Posts
    3,069
    Blog Entries
    3
    Rep Power
    8

    Default

    One quick point, when looping from 0 you can make the condition < length instead of length - 1

    Java Code:
     for(int i = 0; i < array.length; i++){code}
    Edit: you can problem ignore the first part. I think you understand and meant to leave one empty array element

    You could also consider a while loop nested in the validation clauses.
    Java Code:
    if input Is too high of low
      loop while input is bad
        Prompt for input store in array[I]
      end loop
    end if
    Last edited by sunde887; 04-21-2011 at 02:42 AM.

  4. #4
    Join Date
    Apr 2011
    Posts
    5
    Rep Power
    0

    Default

    It makes perfect sense why I'm getting the exception. As far as I'm aware of (it's too late to check a book right now) you can't have negative subscripts in arrays. If that is true then why will it let one of the if statements allow a negative index and the other not?

    Maybe I'm confused as to when the i++ iterates?

  5. #5
    sunde887's Avatar
    sunde887 is offline Moderator
    Join Date
    Jan 2011
    Location
    Richmond, Virginia
    Posts
    3,069
    Blog Entries
    3
    Rep Power
    8

    Default

    The i++ iterates after the loop is finished with the current cycle. You can test this by printing the value of i in the loop.

    Java Code:
    for(int i = 0 ; i < 10; i++){
      System.out.println(i);
    }
    this shows 0 - 9, so you can see that i++ happens after the statement block. Does this error get thrown only when you input a number < 1 || > 33 on the first input?

  6. #6
    sunde887's Avatar
    sunde887 is offline Moderator
    Join Date
    Jan 2011
    Location
    Richmond, Virginia
    Posts
    3,069
    Blog Entries
    3
    Rep Power
    8

    Default

    The i++ iterates after the loop is finished with the current cycle. You can test this by printing the value of i in the loop.

    Java Code:
    for(int i = 0 ; i < 10; i++){
      System.out.println(i);
    }
    this shows 0 - 9, so you can see that i++ happens after the statement block. Does this error get thrown only when you input a number < 1 || > 33 on the first input?

  7. #7
    Dark's Avatar
    Dark is offline Senior Member
    Join Date
    Apr 2011
    Location
    Camp Lejuene, North Carolina
    Posts
    643
    Rep Power
    4

    Default

    You can use ++i to increment it before the statement executes.
    • Use [code][/code] tags when posting code. That way people don't want to stab their eyes out when trying to help you.
    • +Rep people for helpful posts.

  8. #8
    pbrockway2 is offline Moderator
    Join Date
    Feb 2009
    Location
    New Zealand
    Posts
    4,565
    Rep Power
    12

    Default

    If that is true then why will it let one of the if statements allow a negative index and the other not?
    Maybe I'm confused as to when the i++ iterates?

    You are perfectly free to give a variable - including i in this case - a negative value, and you are perfectly free to use that variable as an array index: its just that you'll get an ArrayIndexOutOfBounds exception when you do.

    The increment step happens after the loop body has finished. But notice that you use the variable i three times as an index into the ball array. The i++ won't help you if you use i as an array index after it has been made negative but before the increment happens.

    In your code you are setting i to a negative value. Look at your code (the body of the for loop) and try and find a place that uses i as an index after you might have made it negative.

  9. #9
    Join Date
    Apr 2011
    Posts
    5
    Rep Power
    0

    Default

    Both of these if statements should cause the value of i to be -1 during the first iteration.
    Java Code:
    			if(ball[i] < 1) //make sure input is positive
    			{
    				System.out.println("Number must be greater than 0");
    				i--;
    			}
    			if(ball[i] > 33) //make sure input is within max boundry
    			{
    				System.out.println("Number must be less than 34");
    				i--;
    			}
    What's confusing me is only during the first if does it give me the OutOfBoundsArray exception. I've ran the program over and over trying to cause the second if statement to force the exception but it won't for some reason.

    What I'm trying to figure out is even though both if statements should make the i variable negative (causing the array subscript to be negative) why does only the top if statement force the exception.

  10. #10
    sunde887's Avatar
    sunde887 is offline Moderator
    Join Date
    Jan 2011
    Location
    Richmond, Virginia
    Posts
    3,069
    Blog Entries
    3
    Rep Power
    8

    Default

    You can add a print statement to your loop like this
    Java Code:
    loop
      print i
      do all stuff in loop
      print i
    end loop
    This will let you see the value of i when the loop begins and ends, thus allowing you to see what the value of i is, and why it only gets negative on the first iteration.

    Like stated earlier, you can either validate inside the loop(a loop inside a loop, loopception) or you can use a while loop for the entire thing instead of a for loop. With this approach the i is not incremented by the loop itself.

    Java Code:
    declare i
    while loop
      get input
      if < 1 || > 33 
        print message
        continue
      end if
      if input is good
        store input
        increment
      end if
    end while
    This approach allows you to control when the counter is incremented. It shouldn't be incremented when the input is incorrect, instead it should only be incremented for correct input.

  11. #11
    Join Date
    Apr 2011
    Posts
    5
    Rep Power
    0

    Default

    What I did for a quick fix was to just make the ball array have 6 elements and leave the 0 element at 0 so when it was subtracted from I wouldn't go negative. I feel like this was kind of a cheap fix but at least the error wasn't happening and all parts of the specifications were met.

    This program obviously isn't as efficient as it could be but the teacher asked for specific messages for when the number was too high and too low or else I would've just done it in a loop and made it easier. Also, the class asked that we used things from recent chapters and all that.

    I did put in the output codes to show me what the value of i was both before and after the "i--;" and they were the same.

    Maybe this is one of those urban legends of Java? haha

  12. #12
    sunde887's Avatar
    sunde887 is offline Moderator
    Join Date
    Jan 2011
    Location
    Richmond, Virginia
    Posts
    3,069
    Blog Entries
    3
    Rep Power
    8

    Default

    Are you not allowed to use while loops? A single while loop instead of the for loop would be the best approach, you would have a nicely working approach instead of a hacked approach.

    Also, as a quick test I created this program to see what happens
    Java Code:
    public class LoopTest{
    	public static void main(String[] args){
    		for(int i = 0; i < 10; i++){
    			System.out.println(i);
    			i--;
    			System.out.println(i);
    		}
    	}
    }
    This code prints -1, 0 ... continued forever.

    I feel like you should test your approach a lot to make sure there aren't any unexpected bugs.

    with the while loop pseudo code you can still allow it to print the correct message. Also, the step section of a for loop doesn't NEED to do anything.

    Java Code:
    for(int i = 0; i < x; i){code}
    
    and
    
    for(int i = 0; i < x; ){code}
    are both perfectly legal. This is loop relies on you to properly change the value of i to eventually meet fail the condition. In your case you wouldn't change i if the guess is too high or too low, instead you would just print a message. If they enter a correct value you would store it and increment i.
    Last edited by sunde887; 04-21-2011 at 07:02 PM.

  13. #13
    Join Date
    Apr 2011
    Posts
    5
    Rep Power
    0

    Default

    Yeah, I could've done the code more efficiently but I was mainly following examples in the book to show I was paying attention. It's already turned in fine and met all the requirements. I just couldn't find an answer why one if statement turned the subscript negative and caused an out of bounds array exception and the other if statement that did the same never caused the exception.

Similar Threads

  1. 2d Array, Array out of bounds exception
    By Bmorebob in forum Advanced Java
    Replies: 2
    Last Post: 03-24-2011, 10:34 PM
  2. array going out of bounds?
    By jabo in forum New To Java
    Replies: 9
    Last Post: 04-02-2010, 11:08 AM
  3. Array out of bounds exception 20.
    By dropt in forum New To Java
    Replies: 4
    Last Post: 09-21-2009, 11:32 PM
  4. Array Index out of bounds
    By leapinlizard in forum New To Java
    Replies: 5
    Last Post: 04-29-2009, 06:11 AM
  5. why is my array out of bounds?
    By Phobos0001 in forum New To Java
    Replies: 3
    Last Post: 03-24-2008, 02:20 AM

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •