0

Fairly new to java and programming.

Wrote this recursive method, with the objective of asking for a valid string that is both an integer and greater than 0:

private int getDimension(String tableElement){
    Integer Input= 0;
    System.out.println("Define table rows "+tableElement+"'s."
                       +"Enter an integer >= 1:");

    if( !Reader.hasNextInt() || (Input=Input.parseInt(Reader.nextLine())) <= 0)
        return getDimension(tableElement);
    return Input;
}

I'd like to stick to using a short and recursive method. It seems to handle the >= 0 logic fine, but blows up when i pass it something other than an integer.

Can someone explain why does that happen to me please?

GhostCat
  • 127,190
  • 21
  • 146
  • 218
  • 1
    ParseInt throws an exception that you need to handle using a try-catch block. Using recursion to handle this sort of problem is not a good idea. – David Choweller Feb 25 '17 at 19:19
  • 1
    `Input.parseInt(Reader.nextLine())` would throw an exception if it's not an integer. To keep it short, I'd flag the function with the `throws` keyword and wrap it in a try catch at the calling statement. – Drew Kennedy Feb 25 '17 at 19:19
  • Thanks guys. On a side note: Why would it be bad practice to use recursion (@DavidChoweller)? –  Feb 25 '17 at 19:21
  • Recursion adds the overhead of function calls and stack space. That overhead is sometimes justified if the recursion is used in an elegant declarative way typical of functional programming, but not in cases like this, where a simple loop would suffice. – David Choweller Feb 25 '17 at 19:25
  • You **only** want do a loop. You can use recursion for that, but that is over-complicating things. – GhostCat Feb 25 '17 at 19:25

3 Answers3

1

hasNextInt() doesn't actually consume your input, so you're stuck with the same non-int input on your next call.

bluecanary
  • 81
  • 5
0

Simply spoken, your code doesn't make much (any?) sense.

First of all, there is not really a point in using a recursive method that asks the user for input; and that does not at all do anything about the argument passed to it!

private int getDimension(String tableElement){
  Integer Input= 0;

Bad: you keep up mixing int and `Integer. They are not the same. And - read about java coding style guides. Variable names start lower case!

if( !Reader.hasNextInt() || (Input=Input.parseInt(Reader.nextLine())) <= 0)

The first condition gives:

true: when there is NO int ... 
false: when there is an int

true leads to: calling your method again without retrieving a value from the reader.

false leads to parsing an int; and checking its value for <= 0.

In one case, you are doing a recursive call; completely ignoring the input you got from the reader; in the other case, you returning 0; or that value in input.

Solution: do something like:

while (true) {
  if (reader.hasNextInt()) {
    input = reader.nextInt();
    break;        
  }
  // there is no number!
  read.nextLine(); // consume & throw away non-number!
  print "Enter a number"
}

instead.

But seriously: start with throwing away this code.

Final side note: you do Input.parseInt() ... but that is a static method on the Integer class. Just call that as Integer.parseInt() instead! But as said; throw away your code; and learn how to properly use that Scanner class; start reading here.

Community
  • 1
  • 1
GhostCat
  • 127,190
  • 21
  • 146
  • 218
  • Lol. I apologise for the lack of clarity in my code. The pseudo-code really broke it down for me. Thanks ! –  Feb 25 '17 at 19:29
  • @TaimurAhmed Well, your code is so overly confusing, that even my pseudo code was half wrong. Seriously; your problem is that your code confuses the **hell** out of everybody. I will put some more updates in ... – GhostCat Feb 25 '17 at 19:31
  • OK, updates are in. Wow, that code of yours cost both of us some minutes of our life ... – GhostCat Feb 25 '17 at 19:35
0

Because the user can enter anything, you must always read in the line, then compare it:

String num = Reader.nextLine();
return num.matches("[1-9][0-9]*") ? Integer.parseInt(num) : getDimension(tableElement);

Here I've use regex to figure out if it's a positive number; the expression means "a 1-9 char followed by 0 or more of 0-9 chars"

Bohemian
  • 365,064
  • 84
  • 522
  • 658