How to repeat until the user enters an integer? - java

This is currently my code.
What I want it to do, is accept up to 10 numbers in an array then do and display some math for them. What I managed to do, is catch errors, then stop the program.
What I want it to do, is keep the program running until the user correctly enters an integer.
I managed to do something similar for my y/n string, but I don't know how to do it for integer arrays.
public static void main(String[] args) {
Scanner input = new Scanner (System.in);
int i=0, numberlist[] = new int [10];
String yn=null;
while (i < 10)
{
try {
System.out.print("Please enter your number\n");
numberlist[i]=input.nextInt();
System.out.print("Would you like to enter another number? (y/n)\n");
yn=input.next();
i++;
if (i==10)
{System.out.println("You reached the maximum amount of numbers\n");
break;}
if (yn.equals("n"))
break;
else if (!yn.equals("y"))
while (true)
{System.out.print("Please only enter a 'y' for yes or 'n' for no next time.\nDo you understand? Type 'y' to continue\n");
yn=input.next();
if (yn.equals("y"))
break;
}
}catch (Exception e){System.out.println("Please enter the correct number(integers only) next time.");}
}
int max=numberlist[0], min=numberlist[0], numlength = i, sum=0;
float average;
for(i = 0; i < numlength; i++) {
if(numberlist[i] > max)
max = numberlist[i];
}
for(i = 0; i < numlength; i++) {
if(numberlist[i] < min)
min = numberlist[i];
}
for(i = 0; i < numlength; i++) {
sum=numberlist[i]+sum;
}
average = (float)sum/(float)numlength;
System.out.println("Your Sum is: "+sum);
System.out.println("Your Average is: "+average);
System.out.println("Your Maximum is: "+max);
System.out.println("Your Minimum is: "+min);
}

Move your error handling for numbers inside the while loop so that any exceptions don't break the flow out of the loop and end the program.
while (i < 10) {
try {
System.out.print("Please enter your number\n");
numberlist[i] = input.nextInt();
System.out.print("Would you like to enter another number? (y/n)\n");
yn = input.next();
i++;
if (i == 10) {
System.out.println("You reached the maximum amount of numbers\n");
break;
}
if (yn.equals("n"))
break;
else if (!yn.equals("y"))
makeUserUnderstand(input,
"Please only enter a 'y' for yes or 'n' for no next time.");
} catch (InputMismatchException e) {
makeUserUnderstand(input,
"Please enter the correct number (integers only) next time.");
}
}
I've moved out the common "Do you understand?" part into a method.
private static void makeUserUnderstand(Scanner input, String msg) {
while (true) {
System.out.println(msg);
System.out.println("Do you understand? Type 'y' to continue\n");
if (input.next().equals("y"))
break;
}
}

First of all, don't catch Exception. You should catch only the specific exceptions that you care about and know might occur in your code. Any other exceptions indicate a serious problem and by catching them, you can accidentally squelch important information that indicates a bug that needs your attention.
With that said, you can solve your problem by making your try block smaller by only wrapping the code that reads input. In addition, create a loop that checks a flag that indicates if an error occurred. The flag can be set in the catch block when an error occurs parsing the input into an integer.
If you have trouble translating my description into code, feel free to ask about the details.

Related

How to reprompt user if two conditions are met?

I'm supposed to create an array/list of 10 doubles and allow the user to type '99999' to quit. I'm also supposed to give the user an error if no doubles are entered, i.e. if the user types '99999' before any double values.
I know I could put an if (doubleList.isEmpty()) at the end of the while loop and just end the program that way, but I want to keep prompting the user for values if they enter 99999 first.
I tried entering a if(doubleList.isEmpty())" in the while(true) loop but couldn't get it to work.
The code below somewhat works.
import java.util.*;
public class DistanceTesting
{
public static void main(String[] args)
{
//Almost works, but not quite. I can't figure out how to reprompt the user if the list is empty
List<Double> doubleList = new ArrayList<>();
int count = 0;
double sum;
double average;
double number;
Scanner input = new Scanner(System.in);
System.out.println("Enter up to 10 doubles: ");
number = input.nextDouble();
if (number == 99999)
{
System.out.println("Error: you must enter at least one double.");
}
while (true)
{
count++;
System.out.println("Enter a double(or press 99999 to quit): ");
number = input.nextDouble();
if (number == 99999)
{
break;
}
if (count == 10)
{
break;
}
else
{
doubleList.add(number);
}
}
}
}
If I understand your question correctly, you will want to put if(doubleList.isEmpty()) inside the if (number == 99999) block, and delete the lines before the while loop and just handle it inside the loop.
if (number == 99999)
{
if(doubleList.isEmpty())
{
System.out.println("Error: you must enter at least one double.");
count--;
continue;
}
else
{
break;
}
}
What this does is when the user inputs 99999, it then checks if the list is empty. If it is, print the error, subtract count (since they didn't input a double you wanted), and continue starts again from the beginning of the loop, prompting them again

JAVA: if statement inside a for loop and exiting from a for loop

Good day guys, I am new in this. I am doing an assignment for my prog unit, so please bear with me.
So what I have to do is to write up a code that can input people's ages, from integers between 1 to 120 inclusive. The user then have to calculate the average age, and should be calculated as a real number. But the user has to input age values until the user enters 0, which is to stop the program then output the average. If the user enters an age that is invalid, then the program should continue to re-prompt the user until they enter a valid age.
So I did my part. I created a code and I come up with this:
public static void main(String[] args)
{
int ageValue = 0;
double getAge;
getAge = inputAge();
System.out.println("Average age is: " + getAge);
}
public static double inputAge()
{
int ageValue = 0;
double avgAge = 0;
Scanner sc = new Scanner(System.in);
for (int i = 1; i <= 120; i++)
{
System.out.println("Enter age");
ageValue += sc.nextInt();
avgAge = ageValue / (double) i;
if (ageValue == 0)
{
System.out.println("Average age is: " + avgAge);
System.exit(0);
}
while (ageValue < 0 || ageValue > 120)
{
System.out.println("Invalid input. Try again!");
ageValue = sc.nextInt();
}
}
return avgAge;
}
Now I laid down my code and I got my average formula somehow working. Now, the problem is that when I press 0, it doesn't prompt the "if" statement. However, when the first "Enter your age" prompt comes up and I pressed 0, the "if" statement worked. But for each iteration, the program won't let me execute the statement.
On the other hand, I am also struggling to figure out how to exit a loop without using break or System.exit() because that will give me zero marks. What I wanted is when I press 0, it should exit the loop and output the average, like what the task said.
I don't know if you guys can get it.. Is the code right? Am I on the right track? Am I missing something???
Cheers
You could consider a do while loop approach. This would allow your code to naturally run once, and exit once the user enters 0:
int ageValue = 0, numOfAges = 0, sumOfAges = 0;
do {
System.out.println("Enter age");
ageValue = sc.nextInt();
if (ageValue < 0 || ageValue > 120)
System.out.println("Bad value... try again");
else if (ageValue != 0) {
sumOfAges += ageValue;
numOfAges++;
}
} while (ageValue != 0);
return ((double)sumOfAges / numOfAges);
On the other hand, I am also struggling to figure out how to exit a loop without using break or System.exit() because that will give me zero marks.
You can have another condition in your for loop like this
boolean finished = false;
for (int i = 1; i <= 120 && finished == false; i++)
and replace
System.exit(0)
with
finished = true;
However, I would question why using "break" will score you zero marks. This is exactly the sort of scenario break was intended for.
you can try this approach.
i've corrected a bit the exit condition and the way averaging is done.
the "for" loop you show in your code is limiting the number of sample to 120, but the question don't say so, so i took the liberty to generalise you question to any number of sample to average.
first thing is you should look up "if-else" conditionnal structure, as that was the main point missing in your code.
https://en.wikipedia.org/wiki/Conditional_(computer_programming)
you can think the way the problem is expressed as :
calculate the average in a serie
the serie is keyboard inputted
when zero is inputted, exit the loop and return the current average
when any value out of bound [0,120] is inputted, give a message and continue the loop without changing anything to the serie
when any value inside the bound [1,119] is inputted add the value to the serie and recalculate the average
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class Test
{
public static void main(String[] args)
{
System.out.println("Final Average age is: "+inputAge());
}
private static double inputAge()
{
int ageValue=0;
double avgAge=0;
boolean shouldExit=false;
Scanner sc=new Scanner(System.in);
List<Integer> samples=new ArrayList<Integer>();
// loop until flag is true
while(!shouldExit)
{
System.out.println("Enter age");
ageValue=sc.nextInt();
if(ageValue==0)
{
shouldExit=true;
}
else if(ageValue<0||ageValue>120)
{
System.out.println("Invalid input. Try again!");
}
else
{
// add current input in the samples and calculate average over all the samples
samples.add(ageValue);
avgAge=getAvg(samples);
System.out.println("Current Average age is: "+avgAge);
}
}
sc.close();
return avgAge;
}
private static double getAvg(List<Integer> samples)
{
double avgAge=0;
for(Integer tmp:samples)
{
avgAge+=tmp;
}
return avgAge/(double) samples.size();
}
}

Try Catch Block Not Catching String Input (InputMismatchException)

I am needing to stop the user from entering a string value.
Here is what I've tried so far.
import java.util.InputMismatchException;
import java.util.Scanner;
import java.util.Random;
public class guessinggame
{
public static void main (String[] args)
{
int randomNumber = new Random().nextInt(10);
System.out.println("My number is " + randomNumber + ". ");
System.out.println("I’m thinking of a number between 0 and 9.");
System.out.println("What is your guess:");
Scanner keyboard = new Scanner(System.in);
int guess = keyboard.nextInt();
guess1(guess);
int input = 0;
try{
input = keyboard.nextInt();
}catch (InputMismatchException e){
int guess = keyboard.nextInt();
System.out.println("Invalid.");
}
if (guess < randomNumber) {
System.out.print("your guess was too low.");
}else if (guess > randomNumber){
System.out.print("your guess was too high.");
}else if (guess == randomNumber){
System.out.print("your guess was correct.");
}
}
}
The error I am receiving is: Duplicate local variable guess preventing program from compiling, however I imagine I am also missing bits from making this program do what I want it to.
It needs to only accept integer values as input between 0-9. Anything else (including strings) should return as invalid.
The compiler is giving you the error because you have declared guess twice:
Once at the beginning with int guess = keyboard.nextInt();
Then in the catch clause with int guess = keyboard.nextInt(); again
Also note that you readInt() several times in your code, meaning that you are trying to get user input several times. You should reference guess in your code instead.
If you are often having trouble with compile errors and such, you may want to use an IDE such as Eclipse.
The main error is that you are re-declaring guess in the catch block.
What you really need to do is loop around if invalid data is input
int guess = -1; // some magic number
while (guess <= -1) { // we do not want negative number
try{
guess = keyboard.nextInt();
}catch (InputMismatchException e){
System.out.println("Invalid - try again.");
continue;
}
if (guess >= 0) {
break;
}
System.out.println("We want between 0 and 9 - try again.");
}
// now we have valid value for guess
Edit
As per new requirements
int guess = -1; // some magic number
try{
guess = keyboard.nextInt();
}catch (InputMismatchException e){
// do not need to do anything
}
if (guess < 0) {
System.out.println("Invalid - will exit.");
System.exit(-1);
}
// now we have valid value for guess
int guess = keyboard.nextInt();
should just be
guess = keyboard.nextInt();

Correct user input not matching array values

I've written a portion of code to take a user input, match it to a string value and then use a related double value to make calculations:
double [] currency = new double[] {0.05,0.10,0.20,0.50,1.00,2.00,5.00,10.00,20.00,50.00,100.00};
String [] currencytext = {"$0.05","$0.10","$0.20","$0.50","$1.00","$2.00","$5.00","$10.00","$20.00","$50.00","$100.00"};
Scanner keyboard = new Scanner(System.in);
for (int i = 0; i < currencytext.length; i++) {
boolean valid = false;
while(!valid){
System.out.format("$%.2f remains to be paid. Enter coin or note: ",sum);
String payment = keyboard.next();
if(payment.equals(currencytext[i])){
sum = sum - currency[i];
if(sum == 0) {
System.out.print("You gave " + payment);
System.out.print("Perfect! No change given.");
System.out.print("");
System.out.print("Thank you" + name + ".");
System.out.print("See you next time.");
}
}
if(!(payment.equals(currencytext[i]))) {
System.out.print("Invalid coin or note. Try again. \n");
}
if(payment.equals(currencytext[i]) && currency[i] > sum){
System.out.print("You gave " + payment);
System.out.print("Your change:");
}
}
}
The problem is that when it gets to user input, it doesn't match any string values except for $0.05. It seems to me like its not iterating through the array properly but I can't figure out why. Is anyone able to see a problem here?
This is a possible solution for your problem
Scanner keyboard = new Scanner(System.in);
double [] currency = new double[] {0.05,0.10,0.20,0.50,1.00,2.00,5.00,10.00,20.00,50.00,100.00};
String [] currencytext = {"$0.05","$0.10","$0.20","$0.50","$1.00","$2.00","$5.00","$10.00","$20.00","$50.00","$100.00"};
String payment = keyboard.next();
double sum = 100; // <- Working example - Read sum from keyboard entry
while (sum > 0) {
boolean paymentFound = false;
for (int i = 0; i < currencytext.length; i++) {
if (payment.equals(currencytext[i])) {
sum = sum - currency[i];
paymentFound = true;
if (sum == 0) {
System.out.println("You gave " + payment);
System.out.println("Perfect! No change given.");
// System.out.print("Thank you" + name + ".");
System.out.println("See you next time.");
break;
} else if (sum < 0) {
System.out.println("You gave " + payment);
System.out.println("Your change:" + (-1 * sum));
break;
}
}
}
if (!paymentFound) {
System.out.println("Invalid coin or note. Try again. \n");
}
if (sum > 0) {
System.out.format("$%.2f remains to be paid. Enter coin or note: ", sum);
payment = keyboard.next();
}
}
while-loop will continue until the payment is fullfilled.
for-loop traverse the arrays until a suitable payment is found
If suitable payment is found we substract it from sum. We use break to exit the for-loop in both cases. There is no need to keep searching.
If no suitable payment is found [!paymentFound], we keep on asking.
if (!paymentFound) {
System.out.println("Invalid coin or note. Try again. \n");
}
if (sum > 0) {
System.out.format("$%.2f remains to be paid. Enter coin or note: ", sum);
payment = keyboard.next();
}
The program will end when (sum < 0), in which case the while-loop exits.
I have use println instead of print to improve message legibility.
Too many flaws to point out.
However,
When the currencytext[i] does not match payment, it executes this code:
System.out.print("Invalid coin or note. Try again. \n");
System.out.format("$%.2f remains to be paid. Enter coin or note: ",sum);
payment = keyboard.next();
So, it executes this for all the times that your input does not match currencytext[i].
And, in this block, you have
payment = keyboard.next();
So, it asks for new input, in this block itself. Hence, you get the said output for all inputs except $0.05.
As far as $0.05 is concerned, your first if block executes successfully, and prints no output. So, it moves to the next iteration of the while loop, where again, payment remains the same ($0.05), but currencytext[i] becomes $0.10. SO they do not match, and you get the said output.
How to correct this:
With this code, you need to do a lot of corrections.
I suggest you again start from scratch.
If it doesn't fit, it sets valid to true, so the code just has the chance to check against the first item at currencytext[0], which is $0.05. Then !payment.equals(currencytext[i]) is also true, and your code prints the lines there. Your else ifs are also not properly nested.
I don't know how you are reading input. One improvement you can do is write reading input code in for loop.
Scanner scanner = new Scanner(System.in);
for (... ) {
....
String payment = scanner.nextLine();
....
}

Try-Catch inside a loop

In the below code, I ask the user to give an integer input and if the input is 0 or a negative number, it loops again until the positive number is given. The thing is that if the users presses a letter, my code crashes and despite the fact that I used try-catch in a lot of ways nothing really worked. Any ideas?
I used try-catch inside the loop, but it only worked for one letter input and not correctly.
System.out.print("Enter the number of people: ");
numberOfPeople = input.nextInt();
while (numberOfPeople <= 0) {
System.out.print("Wrong input! Enter the number of people again: ");
numberOfPeople = input.nextInt();
}
The problem in your current code is that you're always trying to read an int so when receiving a non-integer input you can't handle the error in the right way. Modify this to always read a String and convert it into an int:
int numberOfPeople = 0;
while (numberOfPeople <= 0) {
try {
System.out.print("Enter the number of people: ");
numberOfPeople = Integer.parseInt(input.nextLine());
} catch (Exception e) {
System.out.print("Wrong input!");
numberOfPeople = 0;
}
}
//continue with your life...

Categories

Resources