LazyLady LazyLady - 4 months ago 18
Java Question

Scanner accepts only fourth input

I started to learn Java recently, and currently I am working with exceptions.

Program is a game - Number Guessing.

Code below represents class Ticket.

Ticket has serial number, which consists of 8 numbers.

First 7 numbers are the ones chosen by player, and last number is number of ticket printed (it is static variable).

Inputs should be checked so that player can only choose numbers, and numbers must be between 1 and 90. Also, all numbers must be different (we don't consider number of ticket printed).

What question is really about is Scanner.

When I run program, scanner asks player for number two times before it is accepted, even if player types good number first.

Here is the code:

public class Ticket {

private static int serialNum = 0;
private int ticketNum[];

Ticket() {
Scanner sc = new Scanner(System.in);
ticketNum = new int[8];
this.serialNum += 1;
this.ticketNum[7] = serialNum;
System.out.println("Ticket numbers input...");

for (int i = 0; i < 7; i++) {
System.out.println("Choose " + (i + 1) + ". number: ");
try {
if (!sc.hasNextInt()) {
throw new ValueException();
} else {
if (contains(ticketNum, sc.nextInt())) {
throw new DuplicateValueException();
}
if ((sc.nextInt() < 1) || (sc.nextInt() > 90)) {
throw new ValueException();
}
}
} catch (ValueException e) {
System.out.println(e.Message());
i -= 1;
sc.nextLine();
continue;
} catch (DuplicateValueException e) {
System.out.println(e.Message());
i -= 1;
sc.nextLine();
continue;
}

this.ticketNum[i] = sc.nextInt();
}
}

public void printTicketNum() {
System.out.println("Ticket serial number: ");
for (int i = 0; i < this.ticketNum.length; i++) {
System.out.print(ticketNum[i]);
}
}

private boolean contains(int arr[], int val) {
int flag = 0;
for (int i = 0; i < arr.length - 1; i++) {
if (arr[i] == val)
flag++;
}
if (flag > 0)
return true;
else
return false;
}

public static void main(String[] args) {
Ticket t1 = new Ticket();
t1.printTicketNum();
}
}

Answer

Every time you call sc.nextInt(), you're fetching a new integer from the input. For example, in the block where you have

if(contains(ticketNum,sc.nextInt())){
    throw new DuplicateValueException();
}
if((sc.nextInt()<1)||(sc.nextInt()>90)){
    throw new ValueException();
}

you could actually be reading in three separate integers.

You don't want to do that. Instead, you could assign the integer that you fetch to a local variable

int input = sc.nextInt();

and just check the value of that variable each time you need to.