Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scanner returns wrong int value

Java newbie here.

I made a function to simply return an int given by user through Scanner. The goal is to avoid an error if the user does not type an integer, notify them and let them retry.

It works fine if the value is an integer on the first try, but if I type a char (get an error, function "restart") then the function will return the "default" zero. Tried different things but I definitly don't get the logic here.

Here is the code :

  //Initialize the Scanner earlier
  public static Scanner keyBoardRead = new Scanner(System.in);

  public static int intEntry()
  {
  int entry;
  keyBoardRead = new Scanner(System.in);
  if (keyBoardRead.hasNextInt() == true)
    {
    entry = keyBoardRead.nextInt();
    System.out.println("entry variable = "+entry);
    // Here the correct entry prints but doesn't seem to return
    return entry;
    }
  else
   {
    System.out.println("Invalid entry.\n");
    intEntry();
   }
  return 0;
  }

Sample output :

z
Invalid entry.

2
entry variable = 2

// Function exits and output = 0 (?!)

Thanks for your help and please criticize my code :)

like image 310
Pablo Avatar asked Sep 06 '25 03:09

Pablo


1 Answers

I reworked your code a bit as there were a few flaws with it:

public static Scanner keyBoardRead = new Scanner(System.in);

public static int intEntry()
{
    int entry;
    if (keyBoardRead.hasNextInt())
    {
        entry = keyBoardRead.nextInt();
        System.out.println("entry variable = "+entry);
        // Here the correct entry prints but doesn't seem to return
        return entry;
    }
    keyBoardRead.next();
    System.out.println("Invalid entry.\n");
    return intEntry();
}

Here are the changes explained below:

  • You do not need to redeclare new Scanner(System.in) with every call to the method, you state you initially declare it as a class field, so it should be accessible from inside the method each time.
  • Your else statement in general is completely unnecessary because you have a return in your if. If your if is executed, it will never enter the code afterward anyway.
  • You need to return the value from intEntry() with return intEntry() as currently you are just discarding the return value and simply returning 0 unconditionally if else is executed even a single time.
  • You need to use keyBoardRead.next() if an invalid entry is entered in order to move to the next value and discard the previously entered result. You can also use keyBoardRead.nextLine() instead if you wish to discard the entire line instead.
  • Using == true on a boolean value is redundant as you can simply check the boolean directly, so if (keyBoardRead.hasNextInt()) instead of if (keyBoardRead.hasNextInt() == true). Credit to @Joop Eggen for catching it.

Example Run:

hi
Invalid entry.

wrong
Invalid entry.

entries
Invalid entry.

55
entry variable = 55

Note: You have a lot of blank space in the output because you are use println and also using \n in the print so it will move to the next line twice.

Also you could easily create a variant to this solution that utilizes a while loop instead of recursion, which is probably a better way to do it so you cannot possibly run into a stack overflow (and is typically easier to read), but I kept the recursion in to keep it similar to your solution.

like image 144
Nexevis Avatar answered Sep 08 '25 00:09

Nexevis