-1

I'm trying to make a method that gets the user's input of 6 numbers and add them to a Tree set of integers. I'm trying to make a try and catch exception so if the users accidentally enters in a letter it'll catch the exception and ask them to enter in a number. Right now the program crashes when you try to enter in a letter. It'll print out "Invalid" then crashes. I'm not sure whats going on. Can anyone provide some insight?

public static Set<Integer> getTicket()
{
    int userInput;
    TreeSet<Integer> getNumbers = new TreeSet<Integer>();
    Scanner input = new Scanner(System.in);
    System.out.println("Enter your 6 numbers between 1-40: ");
    for (int i = 0; i<6 ; i++)
    {
        try
        {
            System.out.print(i+1 + ": ");
            userInput = input.nextInt();
        }
        catch (InputMismatchException e)
        {
            System.out.println("Invalid");
            userInput = input.nextInt();
        }
    getNumbers.add(userInput);
    }
    System.out.println("Your ticket was: " + getNumbers);
    return getNumbers;
}
OrangePineapple
  • 65
  • 2
  • 2
  • 12
  • Possible duplicate of [Hot to stop the program from crashing after a String is entered instead of an int](http://stackoverflow.com/questions/26375630/hot-to-stop-the-program-from-crashing-after-a-string-is-entered-instead-of-an-in) – qwerty1423 Oct 29 '16 at 06:07

2 Answers2

0

Just a few notes on some of the changes made. From your original code, one thing I noticed that is not really an error but a head scratcher. Both of your methods (getWinning Numbers() and getTicket() ) returned a Set<integer> set, however you did not use it in main. So I simply took the output from the methods and placed them in the main method, where they should be IMHO. Methods like these should do ONE thing and in this case is return a set of integers. No printing or anything else that’s all it does.

I changed the logic in the getTicket() method. I simply set up a loop that continued until you had 6 valid numbers. Inside that loop I use a try statement to weed out the invalid input. The way the try statement is set up is one of many ways that you could accomplish this. As you can see the statement immediately after the try (guess = Integer.parseInt(userInput);) is where the invalid input problem could pop up and throw a NumberFormatException. If the input is invalid, you drop immediately to the catch where we output a message and continue. If the input is valid then we simply check for duplicates and the range of the number. If the numbers are ok then add it to pickedNumbers and increment numberCount.

public class Lottery
{
   public static Set<Integer> generateWinningNumbers()
   {
      Random rndNumbers = new Random();   
      TreeSet<Integer> winningNumbers = new TreeSet<Integer>();
      int max = 40;
      int min = 1;
      int range;
      int sixNum;

      for (int i = 0; i < 6; i++)
      {
        range = max - min + 1;
        sixNum = rndNumbers.nextInt(range) + min;

        while (winningNumbers.contains(sixNum))
        {
          sixNum = rndNumbers.nextInt(range) + min;
        }
        winningNumbers.add(sixNum);
      }
      return winningNumbers;
    }


   public static Set<Integer> getTicket(Scanner input)
   {
     String userInput;
     int guess;
     TreeSet<Integer> pickedNumbers = new TreeSet<Integer>();
     System.out.println("Enter your 6 numbers between 1-40: ");
     int numberCount = 1;
     while(numberCount < 7)
     {
       System.out.print(numberCount +  ": ");
       userInput = input.nextLine();
       try
       {
          guess = Integer.parseInt(userInput); 
          if( guess > 0 && guess < 41 && (!pickedNumbers.contains(guess)) )
          {
             pickedNumbers.add(guess);
             numberCount++;
          }
          else
          {
            if (pickedNumbers.contains(guess))
            {
              System.out.println("Number already picked: " + guess);
            }
            else
            {
               System.out.println("Invalid number. Pick a number between 1-40: " + guess);
            }
          }
        }
        catch (NumberFormatException e)
        {
          // bad input  
          System.out.println("Invalid input: " + userInput);
        }
    }
    return pickedNumbers;
  }
}

Changes in the Main now take advantage of the methods returning a Set of integers for us. We create two Set<Integer> variables (winningTicket and userTicket) then we simply get the returned sets from the methods and output the results as opposed to printing the results from the methods.

public static void main(String[] args) throws IOException
{
  Scanner userInput = new Scanner(System.in);
  boolean done = false;
  String yesNo;
  Set<Integer> winningTicket;
  Set<Integer> userTicket;
  while(!done)
  {
    winningTicket = Lottery.generateWinningNumbers();
    userTicket = Lottery.getTicket(userInput);
    System.out.println("Your ticket was: " + userTicket);
    System.out.println("Winning Numbers: " + winningTicket);
    System.out.print("\nWould you like to try again? ");
    yesNo = userInput.nextLine();
    if(!yesNo.equalsIgnoreCase("y"))
    {
       System.out.println("Done");
       done = true;
    }
 }
 userInput.close();
}   

Hope this helps

JohnG
  • 9,259
  • 2
  • 20
  • 29
  • This is the right idea. Currently, it seems to be the only answer here that actually works; so congratulations for that. It would be really good if you could add some explanation to it though. What was wrong with OP's code, what did you change, and why? OP is less likely to learn something from a "code dump" than an actual explanation. – Dawood ibn Kareem Oct 29 '16 at 22:25
  • @DavidWallace ...This post is carried over from a previous post. The poster had a different problem with this same code. Someone helped and I simply pointed out the invalid input error. They asked how to fix it and I said try something and if it didn't work then post a new question. Which is this one. I was just trying to help. Sorry. – JohnG Oct 29 '16 at 22:51
  • Don't apologise. As I said, this is the best answer here. I'm only suggesting how you could make it even better. – Dawood ibn Kareem Oct 29 '16 at 22:54
  • @David Wallace I am guessing that this is what (update answer) you were suggesting. I will try to be more thorough in the future. – JohnG Oct 29 '16 at 23:52
  • Cool, I've upvoted you now. Thank you for providing a thorough answer. – Dawood ibn Kareem Oct 30 '16 at 00:07
  • @DavidWallace Thank you for your input. – JohnG Oct 30 '16 at 00:09
-1

This happens because you don't catch exceptions inside cath block. for loop doesn't look good here, try while:

public static Set<Integer> getTicket()
{
    int userInput;
    TreeSet<Integer> getNumbers = new TreeSet<Integer>();
    Scanner input = new Scanner(System.in);
    System.out.println("Enter your 6 numbers between 1-40: ");
     int correct = 0;
    while(correct < 6)
    {
        try
        {
            System.out.print((correct+1) + ": ");
            userInput = input.nextInt();
            getNumbers.add(userInput);
            correct++;
        }
        catch (InputMismatchException e)
        {
            System.out.println("Invalid input");
        }
    }
    System.out.println("Your ticket was: " + getNumbers);
    return getNumbers;
}

Also you cant't print collection that simple:

System.out.println("Your ticket was: " + getNumbers);

What you can do, is to use streams:

System.out.println("Your ticket was: " + getNumbers.stream().map(Object::toString).collect(Collectors.joining(" ")));

maxpovver
  • 1,580
  • 14
  • 25