Loop when incorrect input is given? - java

So basically I've been trying to get this small simple code to work but I'm running into the problem of making a loop. What I want to happen is basically this: User enters an Integer, if its not an integer it will display an error and ask for an Integer until and Integer is given. I'm having a difficult time setting up a loop cause I don't quite know what to do. Im pretty new and dumb so this is probably really easy but I'm kind of an idiot and suck at this but I'm learning.
Here's what I have.
import java.util.Scanner;
public class Loop{
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
System.out.println("Enter an Integer: ");
if (scan.hasNextInt()) {
int Index = scan.nextInt();
scan.nextLine();
System.out.println("Index = " + Index);
}
else if (scan.hasNextDouble()) {
System.out.println("Error: Index is Double not Integer.");
}
else {
System.out.println("Error: Index is not Integer.");
}
}
}

You can use while loop for that.
while (true) {
Scanner scan = new Scanner(System.in);
System.out.println("Enter an Integer: ");
if (scan.hasNextInt()) {
int Index = scan.nextInt();
scan.nextLine();
System.out.println("Index = " + Index);
break;
} else if (scan.hasNextDouble()) {
System.out.println("Error: Index is Double not Integer.");
} else {
System.out.println("Error: Index is not Integer.");
}
}

You need to use a loop (for or while) to your code. You can do it like this.
import java.util.Scanner;
public class Loop {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
while (true) {
System.out.println("Enter an Integer: ");
if (scan.hasNextInt()) {
int Index = scan.nextInt();
scan.nextLine();
System.out.println("Index = " + Index);
} else if (scan.hasNextDouble()) {
System.out.println("Error: Index is Double not Integer.");
} else {
System.out.println("Error: Index is not Integer.");
}
// add same condition to break the loop
}
// close the scanner
scan.close()
}
}

Related

Never ending for loop with user input

I am new to java and have just learned how to use user input. I have a for loop that goes through 10 times with user input to ask for a number. If the number is invalid, it should print "Invalid number" and not count towards the increasing for loop. Instead, it just loops forever saying 'Invalid number'.
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
int sum = 0;
Scanner scanner = new Scanner(System.in);
for(int i = 1; i<=10; i++){
System.out.println("Enter number #" + i + " ");
boolean validInt = scanner.hasNextInt();
if(validInt){
int num = scanner.nextInt();
sum += num;
} else{
System.out.println("Invalid Number");
i--;
}
}
System.out.println("Sum was " + sum);
scanner.close();
}
}
The problem is you are updating the iterator i at 2 places.
The better way is to update it according to the condition.
I would also suggest you to make use of wrapper classes for safe integer conversions and handle the exceptions properly like done in the following code:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
int sum = 0;
Scanner scanner = new Scanner(System.in);
for(int i = 1; i<=10; ){
System.out.println("Enter number #" + i + " ");
String input = scanner.nextLine();
try{
int num = Integer.parseInt(input);
sum += num;
i++; // If input is a valid integer, then only update i
}catch(NumberFormatException e){
System.out.println("Invalid Number");
}
}
System.out.println("Sum was " + sum);
scanner.close();
}
}
I think you also can tweak the code using hasNextInt() directly in the while loop.
while (scanner.hasNextInt()) {
int num = scanner.nextInt();
sum += num;
}
I needed to add a
scanner.nextLine();
After the if and else statement to clear the scanner in both situations.

Program crashes when trying to catch exception

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;
}
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
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(" ")));

Re-requesting input from user when an exception occurs

I am new in java. I have written a program in which the user chooses how many numbers he wants to add. If the user enters a string it will throw an exception and the programs tell the user to enter all details again.
My problem is i want the program to ask the user to re enter details from that number which he entered wrong.
Eg: the user chooses to add 4 numbers but he enters the third number as string, the program should ask the user to re-enter from the third number and not the entire details again.
My code is as follow:
import java.io.*;
import java.util.*;
class Add
{
public static void main(String args[]) throws Exception
{
boolean loop=true;
while(loop)
try
{
String yn;
do
{
Scanner s=new Scanner(System.in);
System.out.println("Enter how many numbers to add: ");
int num=Integer.parseInt(s.next());
int a,sum=0;
for(int i=1;i<=num;i++)
{
System.out.println("Enter number["+i+"]: ");
a=Integer.parseInt(s.next());
sum=sum+a;
}
System.out.println("The Sum is:"+sum);
System.out.println("Do you want to continue?(Y/N):");
yn=s.next();
} while(yn.equals("y")||yn.equals("Y"));
}
catch(Exception e)
{
System.out.println("Try Again\n");
}
}
}
You can resolve this, by placing the "retry" one level deeper in the code:
import java.io.*;
import java.util.*;
class Add {
public static void main(String args[]) throws Exception {
boolean loop=true;
Scanner s=new Scanner(System.in);
while(loop) {
try {
String yn;
do {
loop = true;
System.out.println("Enter how many numbers to add: ");
int num=Integer.parseInt(s.next());
int a,sum=0;
for(int i=1;i<=num;) {
try {
System.out.println("Enter number["+i+"]: ");
a=Integer.parseInt(s.next());
sum=sum+a;
i++;
}
catch(Exception e) {
System.out.println("Invalid input. Try Again.\n");
}
}
System.out.println("The Sum is:"+sum);
System.out.println("Do you want to continue?(Y/N):");
yn=s.next();
loop = yn.equals("y")||yn.equals("Y");
} while(loop);
}
catch(Exception e) {
System.out.println("Number of elements invalid. Try Again.\n");
}
}
}
}
As #Zhuinden indicates, one better uses Scanner.nextInt, since it is more generic...
Below code should help
int i =1;
while(i <=num){
System.out.println("Enter number["+i+"]: ");
try{
a=Integer.parseInt(s.next());
sum=sum+a;
i++;
}catch(NumberFormatException ex){
System.out.println("Please enter a valid interger");
}
}
Use additional method that reads single entry until it is valid number:
private static int readNumber(Scanner s) {
Integer value = null;
while (value == null) {
try {
value = Integer.parseInt(s.next());
} catch (NumberFormatException e) {
System.out.println("bad format, try again...");
}
}
return value;
}
Then you can use this method whenever you can read valid number:
System.out.println("Enter how many numbers to add: ");
int num = readNumber(s);
...
System.out.println("Enter number[" + i + "]: ");
a = readNumber(s);
....
Method getNumber(s) guarantee to return only when user give correct integer.
works according to what you want, but not ethical
import java.io.*;
import java.util.*;
class Add
{
public static void main(String args[]) throws Exception
{
boolean loop=true;int pos=0;int num=0,sum=0;
while(loop)
try
{
String yn;
do
{sum=0;num=0;
Scanner s=new Scanner(System.in);
System.out.println("Enter how many numbers to add: ");
num=Integer.parseInt(s.next());
int a;
for(int i=1;i<=num;i++)
{
System.out.println("Enter number["+i+"]: ");
a=Integer.parseInt(s.next());
sum=sum+a;pos=i;
}
System.out.println("The Sum is:"+sum);
System.out.println("Do you want to continue?(Y/N):");
yn=s.next();
} while(yn.equals("y")||yn.equals("Y"));
}
catch(Exception e)
{
Scanner s=new Scanner(System.in);
int a=0;
for(int i=pos+1;i<=num;i++)
{ System.out.println("Enter number["+i+"]: ");
a=Integer.parseInt(s.next());
sum=sum+a;}
System.out.println("The Sum is:"+sum);
}
}
}

How to avoid stack build up?

I'm trying to figure out how I can write this method to avoid the stack buildup from recursively calling the method in the exception?
Here is the wording of my instructions:
Read a number, use an exception handler to make sure it is an int number and then add to the ArrayList object, aryList.
Here is my attempt:
public void createOriginalAryList() {
Scanner keyboard = new Scanner(System.in);
System.out.println("Enter a number: ");
try {
int number = keyboard.nextInt();
aryList.add(number);
while(keyboard.hasNextInt()) {
System.out.println("Enter a number: ");
number = keyboard.nextInt();
aryList.add(number);
}
} catch(InputMismatchException ime) {
System.out.println("Invalid number submitted! Try again.");
createOriginalAryList();
}
System.out.println(aryList);
}
Any suggestions are greatly appreciated!
Simply use a do-while loop:
Scanner keyboard = new Scanner(System.in);
boolean redo = false;
do {
System.out.println("Enter a number: ");
redo = false;
try {
int number = keyboard.nextInt();
aryList.add(number);
while(keyboard.hasNextInt()) {
System.out.println("Enter a number: ");
number = keyboard.nextInt();
aryList.add(number);
}
} catch(InputMismatchException ime) {
redo = true;
System.out.println("Invalid number submitted! Try again.");
}
}
while(redo);
System.out.println(aryList);
Since initializing the Scanner keyboard each time is useless, it is put before the loop.

why does this code not let me input a command after the calculator class is done?

I am trying to make a simple text based operating system and I cant figure out why my code doesn't let me enter a command after the calculator class is done. It is supposed to continue executing the code until I type "off" but this is not the case. Eclipse says it is running but I cant do anything. can someone please help me?
here is my two classes:
public class Calculator extends Start{
public static void calStrt() {
System.out.print("\nEnter operator you wish to use: ");
StringInput = scan.nextLine();
if (StringInput.equals("+")) {
add();
} else if (StringInput.equals("-")) {
sub();
} else if (StringInput.equals("*")) {
mul();
} else if (StringInput.equals("/")) {
div();
} else {
System.out.println("\nSyntax error: Operator not recognized");
System.out.println("Please try again");
calStrt();
}
}
public static void add() {
System.out.print("\nEnter first number: ");
intInput = scan.nextInt();
int intVar1 = intInput;
System.out.print("\nEnter second number: ");
intInput = scan.nextInt();
int intVar2 = intInput;
System.out.println("\nAnswer: " + (intVar1 + intVar2));
}
public static void sub() {
System.out.print("\nEnter first number: ");
intInput = scan.nextInt();
int intVar1 = intInput;
System.out.print("\nEnter second number: ");
intInput = scan.nextInt();
int intVar2 = intInput;
System.out.println("\nAnswer: " + (intVar1 - intVar2));
}
public static void mul() {
System.out.print("\nEnter first number: ");
intInput = scan.nextInt();
int intVar1 = intInput;
System.out.print("\nEnter second number: ");
intInput = scan.nextInt();
int intVar2 = intInput;
System.out.println("\nAnswer: " + (intVar1 * intVar2));
}
public static void div() {
System.out.print("\nEnter first number: ");
intInput = scan.nextInt();
int intVar1 = intInput;
System.out.print("\nEnter second number: ");
intInput = scan.nextInt();
int intVar2 = intInput;
System.out.println("\nAnswer: " + (intVar1 / intVar2));
}
}
import java.util.Scanner;
class Start {
static Scanner scan = new Scanner(System.in);
static String StringInput;
static int intInput;
public static void main(String[] args) {
System.out.println("\nWelcome to RobOS");
passLoop: while (true) {
System.out.print("\nPlease enter password: ");
StringInput = scan.nextLine();
if (StringInput.equals("banana")) {
System.out.print("Logging in, please wait");
System.out.print(".");
System.out.print(".");
System.out.println(".");
System.out.println("\nWelcome User");
outerLoop: while (true) {
System.out.println("\nType \"help\" to see a list of programs");
StringInput = scan.nextLine();
innerLoop: while (true) {
if (StringInput.equalsIgnoreCase("cal")) {
Calculator.calStrt();
continue outerLoop;
} else if (StringInput.equalsIgnoreCase("guess")) {
GuessGame.guess();
continue outerLoop;
} else if (StringInput.equalsIgnoreCase("help")) {
System.out.println("\n\"cal\" uses the calculator");
System.out.println("\"guess\" plays guessing game");
System.out.println("\"help\" shows list of programs");
System.out.println("\"off\" turns RobOS off");
continue outerLoop;
} else if (StringInput.equalsIgnoreCase("off")){
break passLoop;
}
}
}
} else {
System.out.println("\nWrong password. Please try again");
continue passLoop;
}
}
}
}
Brent Nash is correct. To fix the error though, try using instead of scan.nextInt(): Integer.parseInt(scan.nextLine());
Hope this works
Your code is getting into an infinite loop. When you call StringInput = scan.nextLine(), the first time it works fine. I entered cal and I can run the calculator once. The problem is that the second time scan.nextLine() gets called, it's automatically returning an empty string "" as the value of StringInput. Your set of if/else statements in the while(true) have no way to handle this, so it just loops forever.
The deeper rationale is that you call scan.nextInt() to read in the numbers, but the problem is when you read in the second number for the calculator operation, there's still a "\n" sitting on System.in. As a result, when you loop around and call scan.nextLine() again, it doesn't prompt you for anything because it just reads that "\n" that's still sitting on System.in and then that sends you into an infinite loop.

Categories