import java.util.*;
public class AccountClient {
public static void main(String[] args) {
#SuppressWarnings("resource")
Scanner input = new Scanner(System.in);
boolean infiniteLoop = true;
boolean invalidInput;
int id = 0;
// Create array of different accounts
Account[] accountArray = new Account[1000000];
//Initialize each account array with its own unique id and a starting account balance of $100
for (int i = 0; i < accountArray.length; i++) {
accountArray[i] = new Account("name", i, 100);
}
do {
try {
//inner loop to detect invalid Input
do {
invalidInput = false;
System.out.print("Enter an id: ");
if (!(input.hasNextInt())) {
System.out.println("Invalid input. Please enter a numeric id between 0 and 999999, no letters or symbols allowed. Try again.");
invalidInput = true;
input.nextLine();
}
else {
id = input.nextInt();
accountArray[id].setNumberOfTimesOpened(accountArray[id].getNumberOfTimesOpened() + 1);
input.nextLine();
if (accountArray[id].firstTimeAccount()) {
System.out.print("Please enter a name to register to this account: ");
String name = input.nextLine();
accountArray[id].setName(name);
}
}
} while (invalidInput);
boolean exit;
do {
exit = false;
boolean notAnOption;
int choice;
do {
notAnOption = false;
System.out.print("\nMain Menu\n1: check balance\n2: withdraw\n3: deposit\n4: view transaction history\n5: exit\nEnter a choice: ");
choice = input.nextInt();
if (choice < 1 || choice > 5) {
System.out.println("Sorry, " + choice + " is not an option. Please try again and enter a number between 1 and 5 (inclusive).");
notAnOption = true;
}
} while(notAnOption);
switch (choice) {
case 1: System.out.printf("The balance for your account is $%.2f\n", accountArray[id].getBalance());
break;
case 2: {
boolean withdrawFlag;
do {
System.out.print("Enter the amount you would like to withdraw: ");
double withdrawAmount = input.nextDouble();
input.nextLine();
if (withdrawAmount > accountArray[id].getBalance()) {
System.out.printf("Sorry, you only have an account balance of $%.2f. Please try again and enter a number at or below this amount.\n", accountArray[id].getBalance());
withdrawFlag = true;
}
else {
accountArray[id].withdraw(withdrawAmount);
System.out.printf("Thank you. You have successfully withdrawn $%.2f from your account.\n", withdrawAmount);
withdrawFlag = false;
}
} while (withdrawFlag);
}
break;
case 3: {
System.out.print("Enter the amount you would like to deposit: ");
double depositAmount = input.nextDouble();
input.nextLine();
accountArray[id].deposit(depositAmount);
System.out.printf("Thank you. You have successfully deposited $%.2f into your account.\n", depositAmount);
}
break;
case 4: {
accountArray[id].accountSummary();
}
break;
case 5: {
System.out.println("returning to the login screen...\n");
exit = true;
}
break;
}
} while (exit == false);
}
catch (ArrayIndexOutOfBoundsException ex1) {
System.out.println("Invalid input. Please enter an id between 0 and 999999 (inclusive).");
input.nextLine();
}
catch (InputMismatchException ex2) {
System.out.println("Sorry, invalid input. Please enter an id between 0 and 999999 (inclusive) with no letters or symbols.");
input.nextLine();
}
} while (infiniteLoop);
}
}
Hello everyone, I have a program that simulates an ATM machine. It uses the account class which I created to generate an account for a user after they enter an id between 0 and 999999. They can then perform various tasks like view balance, withdraw, deposit, etc. I'm having an issue though with error checking the program. It compiles with no errors and the first time it goes through the loop, it works perfectly. However, if they hit exit and enter another invalid id, It displays the invalid input message twice. I copied the console of what happens below. Can somebody please explain to me why it does this and how to fix it. Also I'm new to java so if anybody can tell me a better way to error check this it would be much appreciated. As of right now if they enter an int value and it isn't in the range of 0 to 999999, I have to have a separate ArrayIndexOutofBoundsException to catch the error. This seems inefficient. Is there a way I can error check if they entered a numeric value and if they did, check again if they entered an input between 0 and 999999? Thanks
Enter an id: f
Invalid input. Please enter a numeric id between 0 and 999999, no letters or symbols allowed. Try again.
Enter an id: 5
Please enter a name to register to this account: Bob
Main Menu
1: check balance
2: withdraw
3: deposit
4: view transaction history
5: exit
Enter a choice: 5
returning to the login screen...
Enter an id: f
Invalid input. Please enter a numeric id between 0 and 999999, no letters or symbols allowed. Try again.
Enter an id: Invalid input. Please enter a numeric id between 0 and 999999, no letters or symbols allowed. Try again.
Enter an id:
I got zero help from anyone but after hours of frustration I realized this was because I failed to put input.nextLine() after I asked the user to pick a choice. This caused the scanner not to be cleared and caused the statement to be printed twice before it got cleared in the inner loop I had at the start. Once i added the input.nextLine() it worked fine.
Related
we have this method
System.out.print("Enter Principal Amount (1k to 1m) ") ;
while (true) {
principal = scanner.nextInt();
if (principal >= 1000 && principal <= 1_000_000)
break;
System.out.println("Enter a value between 1k - 1m");
If person puts in letters instead of numbers the error occurs,
I need to get the program to ask the question to put in numbers instead of letter
Scanner scanner = new Scanner(System.in);
System.out.print("Enter Principal Amount (1k to 1m) ") ;
while (true) {
principal = scanner.nextInt();
// if (scanner.nextInt() != NumberFormat??) What should I write in my mortgage calculator that ->
// --> if numbers are not put (for ex. letters) it would print out ("Please enter numbers letters are invalid")
//System.out.println("Please enter numbers");
if (principal >= 1000 && principal <= 1_000_000)
break;
System.out.println("Enter a value between 1k - 1m");
}
The simplest way to do what you want is to wrap the inside of your loop in a try {} block and catch the InputMismatchException
If the input is an int it will process as it does now; if not then instead of carrying on after the Scanner.nextInt() line, java will execute the contents of your catch(InputMismatchException e) { } block
There's an argument that you should validate the input more explicitly, but that will be more complex and for a beginner learning how to catch exceptions is probably more useful.
while (true) {
try {
principal = scanner.nextInt();
if (principal >= 1000 && principal <= 1_000_000)
break;
System.out.println("Enter a value between 1k - 1m");
}
catch (InputMismatchException e) {
System.out.println("Please enter numbers");
}
}
From the comments, the OP replied:
No, if for ex. user enters "abc", I get = Exception in thread "main" java.util.InputMismatchException at java.base/java.util.Scanner.throwFor(Scanner.java:943) at java.base/java.util.Scanner.next(Scanner.java:1598) at java.base/java.util.Scanner.nextInt(Scanner.java:2263) at java.base/java.util.Scanner.nextInt(Scanner.java:2217) at com.petras.Main.main(Main.java:20)
But I want to get the line "Please enter valid number" //not letter and let him put the number again, how should my code look?
The problem is that your code assumes the user will always enter a valid integer value. Instead, as your comment reply indicates, you have to account for invalid inputs by wrapping scanner.nextInt() in a try/catch block
Scanner scanner = new Scanner(System.in);
System.out.print("Enter Principal Amount (1k to 1m) ") ;
int principal = 0;
while (true) {
try {
principal = scanner.nextInt();
} catch(InputMismatchException ime) {
System.out.println("Invalid input: " + principal + ". Please enter an integer value");
continue;
} catch (Exception e) {
// This is most likely a "true" error. Handle accordingly.
}
if (principal >= 1000 && principal <= 1_000_000)
break;
System.out.println("Enter a value between 1k - 1m");
}
public static void main(String args[])throws IOException{
validNumbers = new int[200];
Scanner sc1 = new Scanner(new File("validNumbers.txt"));
int i = 0;
while(sc1.hasNextInt()) {
validNumbers[i++] = sc1.nextInt();
}
// Creating loop for what the user enters
boolean newValidator = true;
Scanner scanner = new Scanner(System.in);
while(newValidator) {
System.out.print("Enter the account number: ");
String num = scanner.nextLine();
// If found, the calculations will get displayed
if(validator(num)) {
System.out.print("The calculated value to this account is: " + calculator(num));
newValidator = false;
System.out.println("\n" + "Would you like to enter another account number? (y/n)");
String ans = "";
ans = scanner.nextLine();
// Needed the false, if not the code would keep asking to "Enter account number: "
if (ans.equals("y")) {
System.out.print("Enter the account number: ");
String num2 = scanner.nextLine();
System.out.print("The calculated value to this account is: " + calculator(num2));
} else if(ans.equals("n")) {
newValidator = false;
System.out.println("** Program Exit **");
}
}
// Wanted to add a loop for the user to decide if they want to continue iff wrong account is inputed
else {
System.out.println("Not valid account number" + "\n\n" + "Would you like to try again? (y/n)");
String ans = "";
ans = scanner.nextLine();
if(ans.equals("y")) {
newValidator = true;
}
// How the program terminates if the user does not wish to continue
else if(ans.equals("n")) {
newValidator = false;
System.out.println("Not valid input, the program is now terminated!");
}
}
}
}
}
(Using Java) The code is doing the following:
1.) When the user enters a correct number it sees the number(in the file) and adds the digits
2.) When it is not in the file, it knows the number is not there and tells the user to try again and if the user doesn't want to, it ends the program.
***** (Using Java) What the code is not doing:
1.) After they entered the right code, the program is to ask the user if they want to enter another account(with the adding of an account if so). Then this is where I have the problem, the loop is ending after this second go and I need it to keep asking if they want to enter another account number unit the user wants to exit.*****
There's no need to have a nested question asking for another account number, the while loop itself will ask the user again when it repeats.
Simply ask the user if they want to enter another and then exit the loop if the don't. The while loop drops out when "newValidator" is set to false:
boolean newValidator = true;
while(newValidator) {
System.out.print("Enter the account number: ");
String num = scanner.nextLine();
if(validator(num)) {
System.out.println("The calculated value to this account is: " + calculator(num));
}
else {
System.out.println("Not valid account number!");
}
System.out.println("\n\nWould you like to enter another account number? (y/n)");
String ans = scanner.nextLine();
if (ans.equals("n") || ans.equals("N")) {
newValidator = false;
}
}
System.out.println("** Program Exit **");
I recently started learning Java as I have a keen interest in programming. I am currently creating an application that calculates a person's BMI.
Question: Is there a way to return to the previous statement when the user has made a mistake on instead of restarting the whole program (EG: when the line Please enter your weight in pounds executed, the user input a non-integer value and an error prompts out saying Invalid Input, it will then return to the previous line that the user made an error -> Please enter your weight in pounds executed).
If yes, how so?
import java.util.Scanner;
import java.text.DecimalFormat;
public class Body_Mass_Calculation {
private static int gender, inputAnswer;
private static boolean wenttocatch;
private static double myBMI, heightInch, weightPound, weightKilo, heightMeter;
private static Scanner input_1 = new Scanner(System.in);
private static DecimalFormat df2 = new DecimalFormat("#.##");
//Questions + Calculation
static void myMethod() {
try {
System.out.println("Please enter gender. 1-- Male 2--Female");
gender = input_1.nextInt();
while (gender > 2 || gender < 1) {
System.out.println("Invalid input!");
System.out.println("Please enter gender. 1-- Male 2--Female");
gender = input_1.nextInt();
}
if (gender == 1 || gender == 2) {
System.out.println("Please enter your height in inches. ");
heightInch = input_1.nextInt();
System.out.println("Please enter your weight in pounds. ");
weightPound = input_1.nextInt();
heightMeter = heightInch * 0.0254;
weightKilo = weightPound * 0.45359237;
myBMI = weightKilo / (heightMeter * heightMeter);
}
if (gender == 1) {
if (myBMI >= 27.8)
System.out.println("Your body-mass-index is " + df2.format(myBMI) + " this is considered high ! \n \n");
else
System.out.println("Your body-mass-index is " + df2.format(myBMI) + " this is not considered high ! \n \n");
}
if (gender == 2) {
if (myBMI >= 27.3)
System.out.println("Your body-mass-index is " + df2.format(myBMI) + " this is considered high ! \n \n");
else
System.out.println("Your body-mass-index is " + df2.format(myBMI) + " this is not considered high! \n \n");
}
System.out.println("Do you wish to continue? Enter: 1 -> Yes, 2 -> No.");
inputAnswer = input_1.nextInt();
System.out.println("Invalid Input !");
if (inputAnswer == 2) { //If input = 2, Program executes line below
System.out.println("Thank You for using this shitty app !");
System.exit(2);
} else if (inputAnswer == 1) {
myMethod();
}
} catch
(Exception e) {
input_1.next();
wenttocatch = true;
System.out.println("Invalid input !");
input_1.nextLine();
myMethod();
}
}
public static void main(String[] args) {
//Executes Function/Method
System.out.println("Welcome ! \n ");
myMethod();
}
}
No, you can't. The solution is to write a method that takes care of it. Instead of writing a ton of code and repeating yourself, you use a method to encapsulate some functionality, so that you can invoke it a lot without copying code. For example, instead of:
System.out.println("Please enter gender. 1-- Male 2--Female");
gender = input_1.nextInt();
while (gender > 2 || gender < 1) {
System.out.println("Invalid input!");
gender = input_1.nextInt();
}
you really just want to write something like:
gender = askInt("Please enter gender. 1-- Male 2-- Female", 1, 2);
where the askInt is a method you write which takes the text you want to show as prompt, along with the smallest and largest valid value.
Now that you have this function, you can expand its functionalities and all the code that uses this function gets the functionality automatically. So, if you add 'catch invalid input exceptions and re-ask' functionality to this one method, ALL the questions get it.
int askInt(String prompt, int min, int max) {
int result;
while (true) {
System.out.println(prompt);
result = input.nextInt();
if (result >= min && result <= max) return result;
System.out.println("Invalid input!");
}
}
This basic loop will keep looping until the if clause is triggered, causing the method to return, which is the only way out. You can now add handling for NumberFormatException within this one method, within the while loop. You can't go back to the line that caused the problem, but you can go forward, and in a while loop, going forward automatically jumps back to the start (i.e., that's how to go 'backwards'). So, we mix a while loop (which can go backwards) and a catch block, and that's how to solve the problem. And then we put all this in a method, so that we can write this code only once, instead of having to repeat it every time.
You can do it by using a do { _code1 } while (_condition) which execute the _code until _condition is false.
And _code1 is a try {}catch which will catch any exception (error) thrown from inside the try {} block.Here the exception (error) is thrown if the user enters a character instead of a digit.
System.out.println("Please enter gender. 1-- Male 2--Female");
int gender = 0 ;
do {
try {
if (gender == -1) {
System.out.println("Invalid input!");
System.out.println("Please enter gender. 1-- Male 2--Female");
}
gender = input_1.nextInt () ;
}catch (Exception e){
gender = -1 ;
}
}while (gender > 2 || gender < 1);
The following code below asks the user to enter a number. Then it prompts the user to enter more numbers. When they exit the program they display the highest number entered. How could I convert this code to ask for the gender of a person then age. So the output of the program would state the highest girl age is ____ and the highest boy age is _______? Right now its gender neutral and just complies the highest age.
import javax.swing.JOptionPane;
public class largestNumb{
public static void main(String[] args) {
int highestNumber;
boolean firstNumberEntered = false;
int firstNumber;
do {
String firstNumberInput = JOptionPane.showInputDialog("Enter the first number: ");
try {
firstNumber = Integer.parseInt(firstNumberInput);
firstNumberEntered = true;
}
catch (NumberFormatException e) {
JOptionPane.showMessageDialog(null, "Invalid number! Please try again.");
firstNumber = 0;
firstNumberInput = JOptionPane.showInputDialog("Enter the first number: ");
}
} while (!firstNumberEntered);
highestNumber = firstNumber;
String numberInput = JOptionPane.showInputDialog("Enter another number, or Q to quit");
while (!numberInput.equalsIgnoreCase("Q")) {
int number;
try {
number = Integer.parseInt(numberInput);
if (number > highestNumber) {
highestNumber = number;
}
}
catch (NumberFormatException e) {
JOptionPane.showMessageDialog(null, "Invalid number!");
}
numberInput = JOptionPane.showInputDialog("Enter another number, or Q to quit");
}
JOptionPane.showMessageDialog(null, "The highest number was: " + highestNumber);
}
}
You can ask for the gender in another showInputDialog method.
Change the showInputDialog from an int to a collection of values, it can be an array with a length of 2 to store the highest age for the gender, it can be a map where the key is the gender, the limit is the sky
You will need to work in your validations:
If you are asking ages, shouldn't that be stated when you are asking the data?
What will happen if the user inputs a negative number?
Would you accept an age of 1345 years?
What if it the text is empty, a character different to 'q'?
I would suggest either placing another showInputDialog message within each loop or creating an if statement to specify the gender.
You need to maintain two different variables which will keep track of the highest age for each girl and boy respectively. You do not need to add any additional in this case. Add code to ask the user to enter gender (validate the data) and ask for age. Based on gender do the separate calculation.
while(...)
{
//Ask for gender and validate
//Ask for age and validate
switch(gender)
{
case 'M':
//maleHigestAge calculation here
break;
case 'F':
//femaleHigestAge calculation here
break;
}
}
//display maleHigestAge and femaleHigestAge with formated string
I am trying my hand a few basic do-while codes, and am running into a couple of problems.
I want the code to ask the user to input 1 of 3 options (choosing which group they would like to add a number to, or to exit and total), give an error if they input an irrelevant option, and then total all ints at the end for each group.
public static void main(String[] args) {
String answer = "default";
int grp1 = 0;
int grp2 = 0;
int input1 = 0;
int input2 = 0;
do{
System.out.println("Make a selection:\n");
System.out.println("A: Enter a number for Group 1.");
System.out.println("B: Enter a number for Group 2.");
System.out.println("X: Exit and total the numbers for each group.\n");
System.out.println("Select your option: ");
answer = keyboard.next();
if (answer.equalsIgnoreCase("A")){
System.out.println("Enter int: ");
input1 = keyboard.nextInt(); // add an int to grp1
}
else if (answer.equalsIgnoreCase("B")){
System.out.println("Enter int: ");
input2 = keyboard.nextInt(); // add an int to grp2
}
else if (answer.equalsIgnoreCase("X")){
} // exit and total
else {
System.out.println("Invalid option - Try again.");
} // Invalid input - restart
}
while (answer.equals("A") || answer.equals("B"));
grp1 += input1;
grp2 += input2;
keyboard.close();
System.out.println("Group 1's total is: + grp1);
System.out.println("Group 2's total is: + grp2);
}
I need the to add a qualifier for if the user does not input a valid option, I tried using else:
else {
System.out.println("Invalid option - Try again.")
}
but this just skips to printing the totals, and does not ask the user for another input. How would I best achieve this?
Also,
grp1 += input1;
grp2 += input2;
Only counts the lasted entered int, is there a way to have it add all the entered ints?
Any help would be greatly appreciated, even outside of the questions I asked.
I think you have two confusions.
1) The "while" line in your code applies to the "do" block above it. That means that based on where the grp1 += and grp2 += lines are, they will only ever be run once. I suggest moving those calls to the end of the loop. You could move each line inside the relevant if block so that the code is run every time the user successfully enters a number after A or B.
2) The while condition is asking if the user entered "A" or "B". It's saying if they did, continue looping by going back to "do". If they entered literally anything else (any invalid answer), it will stop and run the code after the "while" line. I think what you really want is while (!answer.equals("X")), which will continue the loop until the user correctly enters an "X" character.
You'll also want to move those grp += lines up a bit.
Just change the condition inside while And also shift the totalling logic
do{
System.out.println("Make a selection:\n");
System.out.println("A: Enter a number for Group 1.");
System.out.println("B: Enter a number for Group 2.");
System.out.println("X: Exit and total the numbers for each group.\n");
System.out.println("Select your option: ");
answer = keyboard.next();
if (answer.equalsIgnoreCase("A")){
System.out.println("Enter int: ");
input1 = keyboard.nextInt(); // add an int to grp1
grp1 += input1;
}
else if (answer.equalsIgnoreCase("B")){
System.out.println("Enter int: ");
input2 = keyboard.nextInt(); // add an int to grp2
grp2 += input2;
}
else if (answer.equalsIgnoreCase("X")){
} // exit and total
else {
System.out.println("Invalid option - Try again.");
} // Invalid input - restart
}
while (!answer.equals("X"));
keyboard.close();
This will make your do while loop running i.e showing options to user until they wishes to exit. And also group total would be updated properly. I have updated answer based on answer by #Devin Howard