Handling Exceptions in Java - How to give user another chance? - java

Hey guys so i've been trying to answer this question for hours:
Write a program that asks the user to input a set of floating-point values. When the
user enters a value that is not a number, give the user a second chance to enter the
value. After two chances, quit reading input. Add all correctly specified values and
print the sum when the user is done entering data. Use exception handling to detect
improper inputs.
I've tried a few different things but i always have the same problem. Once something that isn't a number is given as input, the program outputs the message prompting for another input however the chance is not given, that is to say after 1 incorrect input it prints that message and jumps straight to printing the sum. The best i could do is below i'm just not sure how to approach this problem. Any help is greatly appreciated.
import java.util.Scanner;
import java.util.InputMismatchException;
public class q6{
public static void main(String[] args){
Scanner in = new Scanner(System.in);
boolean firstChance = true;
boolean secondChance = true;
double sum = 0;
while (secondChance){
try{
while (firstChance){
try{
System.out.print("Please enter a number: ");
double input = in.nextDouble();
sum = sum + input;
}
catch (InputMismatchException ex){
firstChance = false;
}
System.out.print("Please enter a number to continue or something else to terminate: ");
double input = in.nextDouble();
sum = sum + input;
firstChance = true;
}
}
catch (InputMismatchException e){
secondChance = false;
}
}
System.out.print("The sum of the entered values is " + sum);
}
}

i'm just not sure how to approach this problem
Pseudocode could be as follows:
BEGIN
MAX_INPUT = 2;
i = 0;
WHILE i < MAX_INPUT
TRY
num = GET_NUM();
CATCH
continue;
FINALLY
i++
END WHILE
END

Since the parsing of input to double is not successful, the scanner does not go past the given input. From javadoc Scanner
Scans the next token of the input as a double. This method will throw
InputMismatchException if the next token cannot be translated into a
valid double value. If the translation is successful, the scanner
advances past the input that matched.
Since the translation is not successful, it does not advance. So, in the catch block you could call in.next() to skip the token.

You could use an integer counter instead of the boolean variables firstChance and secondChance and do something like:
int attempts = 0;
while(attempts < 2) {
try {
//Get user input - possible exception point
//Print sum
} catch(InputMismatchException e) {
attempts++;
//Continue?
}
}

import java.util.*;
public class q6 {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
double inputNumber, sum = 0.0;
int correctCount = 0, wrongCount = 0;
while(wrongCount <=1) {
System.out.println("Please enter a numeric floating value:");
try {
inputNumber = in.nextDouble();
correctCount++;
sum += inputNumber;
if(correctCount >= 2)
break;
} catch(InputMismatchException e) {
wrongCount++;
in = new Scanner(System.in);
continue;
}
}
System.out.println(sum);
}
}

You need to break your while loop when you encounter a "bad" input. Then, you'll need to set firstChance to true again, so you can access the second while, you also will need a counter that counts the number of the attempts (I named it chances):
int chances = 0;
while (secondChance){
firstChance = true;
try{
while (firstChance){
try{
System.out.print("Please enter a number: ");
double input = in.nextDouble();
sum = sum + input;
}
catch (InputMismatchException ex){
chances ++;
in = new Scanner(System.in);
firstChance = false;
}
if(!firstChance && chances < 2)
break;
if(chances >= 2) {
System.out.print("Please enter a number to continue or something else to terminate: ");
double input = in.nextDouble();
sum = sum + input;
firstChance = true;
}
}
}
catch (InputMismatchException e){
secondChance = false;
}
}

As stated in my comment, in order to not deal with Scanner wrong read, it would be better to use Scanner#nextLine() and read the data as String, then try to parse it as double using Double#parseDouble(String) since this method already throws NumberFormatException and you can handle this error. Also, it would be better that your code could handle more than 1 request (if your teacher or somebody else asks to do this):
final int REQUEST_TIMES = 2;
double sum = 0;
for(int i = 1; i <= REQUEST_TIMES; i++) {
while (true) {
try {
if (i < REQUEST_TIMES) {
System.out.print("Please enter a number: ");
} else {
System.out.print("Please enter a number to continue or something else to terminate: ");
}
String stringInput = in.nextLine();
double input = Double.parseDouble(stringInput);
sum += input;
} catch (NumberFormatException nfe) {
System.out.println("You haven't entered a valid number.");
break;
}
}
}

The logic is to read the input once, if it is correct then display the sum, else read the input again and display the sum if the input is correct.
public class q6 {
static int trial = 0;
public static void main(String[] args) {
double sum = 0;
while (trial <= 2) {
Scanner in = new Scanner(System.in);
try {
trial++;
System.out.print("Please enter a number: ");
double input = in.nextDouble();
sum = sum + input;
trial=3;
} catch (InputMismatchException ex) {
trial++;
if (trial == 4){
System.out.println("You have entered wrong values twice");
}
}
}
if (trial <= 3){
System.out.print("The sum of the entered values is " + sum);
}
}
The above program is just a rough idea, you can improve this to adapt to your need.

Related

Java Conditional Statement Exercises: Input numbers from keyboard and find their sum and use input "EXIT "to break the loop

I'm trying to create a loop by entering the number to be added and then blocking the loop with a "exit" input from the user..but it's not working properly.
import java.util.Scanner;
public class main {
public static void main(String[] args)
{
int i,n=0,s=0;
double avg;
{
System.out.println("Input the numbers : ");
}
for (i=0;i<100;i++)
{
String input = new java.util.Scanner(System.in).nextLine ();
if(input.equals("exit")){
break;
}
Scanner in = new Scanner(System.in);
n = in.nextInt();
s +=n;
}
System.out.println("The sum of numbers is : " +s);
}
}
You have a couple of problems. One (minor) is that you are creating two scanners. Another (medium) is that your loop is set up to only go up to 100 - this is a magic number, and there's no reason to put in this artificial constraint. But your biggest problem is that you are ignoring the first entry in the loop if it is a number and not 'exit'
{
int i,n=0,s=0;
double avg;
boolean adding = true;
System.out.println("Input the numbers : ");
Scanner sc = new java.util.Scanner(System.in);
while(adding)
{
String input = sc.nextLine ();
if(input.equals("exit")){ // should proably be "EXIT" or equalsIgnoreCase
adding = false;
} else {
try {
int val = Integer.parseInt(input);
s += val;
} catch (NumberFormatException nfe) {
System.err.println ("expecting EXIT or an integer");
}
}
}
System.out.println("The sum of numbers is : " +s);
}
After this line your console does not have any next line or entry to read.
String input = new java.util.Scanner(System.in).nextLine ();

Check for decimal number input in nextInt()

I am trying to get my code to prompt an Error Message whenever the user enters a decimal number/negative number and will continue to loop until a positive number greater than 0 is implemented.
This is what I have so far;
public static void numberFunctions()
{
System.out.println("Calculating a Factorial");
Scanner myScan= new Scanner (System.in);
System.out.println("Please enter the number you'd like to use: ");
int number = myScan.nextInt();
System.out.println(number);
if(number>0)
{
int factorial = 1;
int count;
for (count = number; count >=1; count --)
{
factorial = factorial * count;
System.out.print(count +" * ");
}
System.out.println(" = " + factorial);
}
else
{
System.out.println("ERROR! Please enter a positive number");
}
}
First you can create a method for example
public static int getInteger() {
}
In that method you can ask the user to enter an integer using a try catch block inside a while loop so that way if they enter a double or a String it will catch the Exception and ask the user to try to enter an integer again.
Once you figure that out you can call that method and check if the number returned is greater than 0.
Once you create this method you can always use it to ask for integers from the user.
Add a try/catch block while taking input.
try {
int number = myScan.nextInt();
}
catch(InputMismatchException e) {
System.out.println("Enter integer numbers only");
System.out.println(scanner.next() + " was not valid input.");
}
You are doing ok with the negative number checking part. However if the user enter an invalid string or a real number, this line of code will throw exception so we need to catch that error: int number = myScan.nextInt();
It is also a good practice to always close your Scanner after using it so we will put it in the finally part.
Here is my suggested code for you:
public static void numberFunctions()
{
System.out.println("Calculating a Factorial");
Scanner myScan= new Scanner (System.in);
System.out.println("Please enter the number you'd like to use: ");
try {
int number = myScan.nextInt();
if(number>0)
{
int factorial = 1;
int count;
for (count = number; count >=1; count --)
{
factorial = factorial * count;
System.out.print(count);
if (count != 1) {
System.out.print(" * ");
}
}
System.out.println(" = " + factorial);
}else {
System.out.println("ERROR! Please enter a positive number");
}
}catch(InputMismatchException ex) {
System.out.println("ERROR! Please enter a positive number");
}finally {
myScan.close();
}
}

How to check that the entered input is an integer or not in java?

How to check in this code that the entered input is integer or not if not then ignore the non-integer values and display the rest numbers.
I have done the full coding but for checking the input is integer or not and then printing the value. How should I do it?
import java.util.Scanner;
class ques2
{
public static void main(String[] args)
{
Scanner sc=new Scanner(System.in);
int i,j;
System.out.print("how many number you want to enter= ");
i=sc.nextInt();
int input[]=new int[i];
System.out.println("Numbers should be great then 3");
for(j=0;j<i;j++)
{
input[j]=sc.nextInt();
}
System.out.println("Number entered are:");
for(j=0;j < i;j++)
{
System.out.println(input[j]);
}
System.out.println("Odd numbers are:");
for(j=0;j < i;j++)
{
if(input[j] % 2 != 0)
{
System.out.println(input[j]);
}
}
System.out.println("Palindrome numbers are:");
for(j=0;j < i;j++)
{
int rev=0,n,num;
n=input[j];
while(input[j] > 0)
{
num=input[j] % 10;
rev=num+(rev*10);
input[j]=input[j]/10;
}
if(n == rev)
{
System.out.println(n);
}
}
}
}
You could take a helper function:
public static boolean checkMe(String s) {
boolean amIValid = false;
try {
Integer.parseInt(s);
// s is a valid integer!
amIValid = true;
} catch (NumberFormatException e) {
//not an integer but you could continue with the rest numbers
}
return invalid;
}
You can check it by comparing the ASCII value whether it lies between 91 to 100.
If yes then it will be an Integer.
You can try to use String in lieu of int. Then, you can go ahead with again int using Integer.parseInt(x) because it's already been verified as being valid integer after do-while
String num;
String regex = "[0-9]+"; // to check the string only is made up of digits
Scanner input = new Scanner(System.in);
do {
System.out.println("Please input an integer");
num = input.next();
} while (!num.matches(regex));
int validNumber = Integer.parseInt(num);
/* .
.
. *\
You're already using sc.nextIn() which internally perform a regex-check as in #snr's post and a Integer.parseInt as in charly1212's post.
The only thing you should add is wrap it in a
try {
int i = sc.nextInt();
} catch(InputMismatchException e) {
//skip or repeat?
}
To deal with all cases, where the input is not an int (which includes values > Integer.MAX_VALUE and < Integer.MIN_VALUE)
The solution could look like this method, encapsulating all the input reading
private static int[] readNumbers() {
Scanner sc = new Scanner(System.in);
int i = -1;
while(i < 0){
try {
System.out.print("how many number you want to enter? ");
i=sc.nextInt();
} catch (InputMismatchException e){
System.out.println(sc.next() + " is not a number, try again");
}
}
List<Integer> numbers = new ArrayList<>();
System.out.println("Numbers should be greater then 3");
for(int j = 0; j < i; j++){
try {
numbers.add(sc.nextInt());
} catch (InputMismatchException e){
System.out.println("Skipping input " + sc.next());
}
}
return numbers.stream().mapToInt(Integer::intValue).toArray();
}
...
int input[] = readNumbers();
Please not, that the exception blocks invoke sc.next() to read the current line (which is not integer) and proceed with the next line (the new input), otherwise the scanner would not proceed its position.

Where should I put the variable scanner declaration? "int figureNumber = stdin.nextInt();"

I want to make it so that a user entering the wrong data type as figureNumber will see a message from me saying "Please enter an integer" instead of the normal error message, and will be given another chance to enter an integer. I started out trying to use try and catch, but I couldn't get it to work.
Sorry if this is a dumb question. It's my second week of an intro to java class.
import java. util.*;
public class Grades {
public static void main(String args []) {
Scanner stdin = new Scanner(System.in);
System.out.println();
System.out.print(" Please enter an integer: ");
int grade = stdin.nextInt();
method2 ();
if (grade % 2 == 0) {
grade -= 1;
}
for(int i = 1; i <=(grade/2); i++) {
method1 ();
method3 ();
}
}
}
public static void main(String args[]) {
Scanner stdin = new Scanner(System.in);
System.out.println();
System.out.print(" Welcome! Please enter the number of figures for your totem pole: ");
while (!stdin.hasNextInt()) {
System.out.print("That's not a number! Please enter a number: ");
stdin.next();
}
int figureNumber = stdin.nextInt();
eagle();
if (figureNumber % 2 == 0) { //determines if input number of figures is even
figureNumber -= 1;
}
for (int i = 1; i <= (figureNumber / 2); i++) {
whale();
human();
}
}
You need to check the input. The hasNextInt() method is true if the input is an integer. So this while loop asks the user to enter a number until the input is a number. Calling next() method is important because it will remove the previous wrong input from the Scanner.
Scanner stdin = new Scanner(System.in);
try {
int figureNumber = stdin.nextInt();
eagle();
if (figureNumber % 2 == 0) { //determines if input number of figures is even
figureNumber -= 1;
}
for(int i = 1; i <=(figureNumber/2); i++) {
whale();
human();
}
}
catch (InputMismatchException e) {
System.out.print("Input must be an integer");
}
You probably want to do something like this. Don't forget to add import java.util.*; at the beginning of .java file.
You want something in the form:
Ask for input
If input incorrect, say so and go to step 1.
A good choice is:
Integer num = null; // define scope outside the loop
System.out.println("Please enter a number:"); // opening output, done once
do {
String str = scanner.nextLine(); // read anything
if (str.matches("[0-9]+")) // if it's all digits
num = Integer.parseInt(str);
else
System.out.println("That is not a number. Please try again:");
} while (num == null);
// if you get to here, num is a number for sure
A do while is a good choice because you always at least one iteration.
It's important to read the whole line as a String. If you try to read an int and one isn't there the call will explode.
You can actually test the value before you assign it. You don't need to do any matching.
...
int figureNumber = -1;
while (figureNumber < 0) {
System.out.print(" Welcome! Please enter the number of figures for your totem pole: ");
if (stdin.hasNextInt()){
figureNumber = stdin.nextInt(); //will loop again if <0
} else {
std.next(); //discard the token
System.out.println("Hey! That wasn't an integer! Try again!");
}
}
...

how to only allow one argument at a time

I am allowing the user to enter numbers via command line. I would like to make it so when the user enters more then one number on the command line at a time it displays a message asking for one number then press enter. then carries on.
here is my code. If someone could show me how to implement this I would appreciate it.
import java.util.ArrayList;
import java.util.InputMismatchException;
import java.util.Scanner;
class programTwo
{
private static Double calculate_average( ArrayList<Double> myArr )
{
Double sum = 0.0;
for (Double number: myArr)
{
sum += number;
}
return sum/myArr.size(); // added return statement
}
public static void main( String[] args )
{
Scanner scan = new Scanner(System.in);
ArrayList<Double> myArr = new ArrayList<Double>();
int count = 0;
System.out.println("Enter a number to be averaged, repeat up to 20 times:");
String inputs = scan.nextLine();
while (!inputs.matches("[qQ]") )
{
if (count == 20)
{
System.out.println("You entered more than 20 numbers, you suck!");
break;
}
Scanner scan2 = new Scanner(inputs); // create a new scanner out of our single line of input
try{
myArr.add(scan2.nextDouble());
count += 1;
System.out.println("Please enter another number or press Q for your average");
}
catch (InputMismatchException e) {
System.out.println("Stop it swine! Numbers only! Now you have to start over...");
main(args);
return;
}
inputs = scan.nextLine();
}
Double average = calculate_average(myArr);
System.out.println("Your average is: " + average);
}
}
As suggested in the comments to the question: Just do not scan the line you read for numbers, but parse it as a single number instead using Double.valueOf (I also beautified the rest of your code a little, see comments in there)
public static void main( String[] args )
{
Scanner scan = new Scanner(System.in);
ArrayList<Double> myArr = new ArrayList<Double>();
int count = 0;
System.out.println("Enter a number to be averaged, repeat up to 20 times:");
// we can use a for loop here to break on q and read the next line instead of that while you had here.
for (String inputs = scan.nextLine() ; !inputs.matches("[qQ]") ; inputs = scan.nextLine())
{
if (count == 20)
{
System.out.println("You entered more than 20 numbers, you suck!");
break;
}
try{
myArr.add(Double.valueOf(inputs));
count++; //that'S even shorter than count += 1, and does the exact same thing.
System.out.println("Please enter another number or press Q for your average");
}
catch (NumberFormatException e) {
System.out.println("You entered more than one number, or not a valid number at all.");
continue; // Skipping the input and carrying on, instead of just starting over.
// If that's not what you want, just stay with what you had here
}
}
Double average = calculate_average(myArr);
System.out.println("Your average is: " + average);
}
(Code untested, so there may be errors in there. Please notify me if you got one ;))
String[] numbers = inputs.split(" ");
if(numbers.length != 1){
System.out.println("Please enter only one number");
}

Categories