Using my code I am trying to tell the user to enter not to enter a string until the user an integer but while running the program it is infinite.
public static void main(String[] args) {
int age = 1;
Utilisateur utilisateur = new Utilisateur();
Scanner u = new Scanner(System.in);
System.out.println("Enter your Name: ");
utilisateur.setNom(u.nextLine());
System.out.println("Enter your Surname: ");
utilisateur.setPrenom(u.nextLine());
System.out.println("Enter your Matricule: ");
utilisateur.setMatricule(u.nextLine());
System.out.println("Enter your Sexe: ");
utilisateur.setSexe(u.nextLine());
do {
try {
System.out.println("Enter your Age: ");
utilisateur.setAge(u.nextInt());
System.out.println(utilisateur.detail());
age = 2;
} catch (Exception e) {
System.out.println("Enter a valid age ");
}
}
while (age == 1);
}
}
Okay, so let's start by cleaning up the code a bit. The whole "age" variable is a bit weird. It seems like it's containing some status on whether or not you've read the age. But that's kind of boolean, isn't it? So let's redo the code with that in mind. I'll change the do-while to a simple while first, but we can change it back afterwards. Furthermore, it might be a good idea to rename "u" to "keyboard", or "clavier" if you prefer french.
public static void main(String[] args) {
Utilisateur utilisateur = new Utilisateur();
Scanner clavier = new Scanner(System.in);
System.out.println("Enter your Name: ");
utilisateur.setNom(clavier.nextLine());
System.out.println("Enter your Surname: ");
utilisateur.setPrenom(clavier.nextLine());
System.out.println("Enter your Matricule: ");
utilisateur.setMatricule(clavier.nextLine());
System.out.println("Enter your Sexe: ");
utilisateur.setSexe(clavier.nextLine());
boolean hasEnteredAge = false;
while(!hasEnteredAge) {
System.out.println("Enter your Age: ");
String ageInput = clavier.nextLine().trim(); // remove leading and trailing whitespace. " 21 " becomes "21".
try {
int age = Integer.parseInt(ageInput);
utilisateur.setAge(age);
System.out.println(utilisateur);
hasEnteredAge = true;
} catch (Exception e) {
System.out.println("Enter a valid age.");
}
}
}
}
Notice that I moved the variable to the beginning of the loop, which is where we need to know about this fact, and how we initialized it to false. We now have to set it to be true afterwards.
But there is a bit more to do here I think. We have a bunch of prints, followed by inputs. Surely, this can be farmed out to a method, that makes this look a bit nicer? But before we do that, we should take another look at the loop. We can do the loop in a multitude of ways. We can do
do {
System.out.println("Enter your Age: ");
String ageInput = clavier.nextLine().trim(); // remove leading and trailing whitespace. " 21 " becomes "21".
try {
int age = Integer.parseInt(ageInput);
utilisateur.setAge(age);
System.out.println(utilisateur);
break; // this means that we should exit the loop
} catch (Exception e) {
System.out.println("Enter a valid age.");
}
}while(true); // So if we ever get here, we're not done.
Here, we're relying on the break to get us out of the loop. This works, but personally I don't like it. It's not a wrong thing to do however, so I'll just leave it in. You can also have it like the old do-while loop:
boolean hasEnteredAge = false;
do {
System.out.println("Enter your Age: ");
String ageInput = clavier.nextLine().trim(); // remove leading and trailing whitespace. " 21 " becomes "21".
try {
int age = Integer.parseInt(ageInput);
utilisateur.setAge(age);
System.out.println(utilisateur);
hasEnteredAge = true;
} catch (Exception e) {
System.out.println("Enter a valid age.");
}
} while (!hasEnteredAge);
Whichever you choose though, it's fine.
Now let me just tackle the issue of the printlines and reads:
If you add a method "prompt" that takes a prompt and returns a string, you can simplify this down quite handily like so:
public class EnterNameHere {
private static Scanner clavier = new Scanner(System.in);
public static String prompt(String prompt) {
System.out.println(prompt);
return clavier.nextLine().trim();
}
// ... The rest is as before.
}
Now, the reading in part becomes very simple:
public static void main(String[] args) {
Utilisateur utilisateur = new Utilisateur();
utilisateur.setNom(prompt("Enter your Name: "));
utilisateur.setPrenom(prompt("Enter your surname: "));
utilisateur.setMatricule(prompt("Enter your matricule: "));
utilisateur.setSexe(prompt("Enter your sex: "));
And an important question arises: If we are to do this for string inputs, why not for integer (int) inputs as well?
I propose:
public static int promptInt(String prompt) {
String value = prompt(prompt);
try {
return Integer.parseInt(value);
} catch(NumberFormatException ignored) {
System.out.println("Invalid number: '" + value + "'");
return promptInt(prompt); // We try again!
}
}
Notice if you would be so kind, that if calling the method promptInt doesn't work, we print an error message and just try again. This will only work for a few hundred times before it all crashes, but that should be enough. (You can of course adapt the while-loop approach from earlier if you don't want that to happen.) This trick of a method or function calling itself multiple times until the work is done is called "recursion" and it is as powerful as looping is. It can be confusing to people who are new to programming, but I think this example is straightforward. If it isn't, you can simply substitute the whole loop thing as mentioned. Of course, there is one method called prompt, and another called promptInt. To avoid any confusion we rename the prompt-method to promptString, and the entire program simply becomes:
public class YourNameHere {
private static final Scanner clavier = new Scanner(System.in);
public static String promptString(String prompt) {
System.out.print(prompt);
return clavier.nextLine().trim();
}
public static int promptInt(String prompt) {
String value = promptString(prompt);
try {
return Integer.parseInt(value);
} catch(NumberFormatException ignored) {
System.out.println("Invalid number: '" + value + "'");
return promptInt(prompt); // We try again!
}
}
public static void main(String[] args) {
Utilisateur utilisateur = new Utilisateur();
utilisateur.setNom(promptString("Enter your Name: "));
utilisateur.setPrenom(promptString("Enter your surname: "));
utilisateur.setMatricule(promptString("Enter your matricule: "));
utilisateur.setSexe(promptString("Enter your sex: "));
utilisateur.setAge(promptInt("Enter your age: "));
System.out.println("You have created an utilisateur: " + utilisateur);
}
}
Plus the definition of Utilisateur of course.
I think this is a much simpler way to do it, by creating methods that does the boring work for you, you can read the code in the main method and immediately understand what is going on. If you need to understand how, you can go up and look at the helping prompt-methods.
You should add u.nextLine(); in catch block in order to skip invalid value entered in the scanner.
Related
I am trying to create a method for error checking input using a try and catch statement with the catch InputMismatch. It is not working can anyone advise why my return statement is not returning the input from the user and storing it in the integer which is called in the main class(call statement is not included).
System.out.print("Please enter the percent achieved for " + sName + ": %");
PromptErrorCheckingPercent(iPercent);
public static int PromptErrorCheckingPercent(int test){
Scanner keyboard = new Scanner(System.in);
boolean valid = false;
while (!valid)
{
try
{
test = keyboard.nextInt();
valid = true;
}
catch(InputMismatchException e)
{
System.out.println("Invalid Input. Please enter a valid integer");
keyboard.nextLine(); //nextLine for a reason
}
}
return test;
What you need is a recursion when InputMismatchException is thrown instead of keyboard.nextLine(); //nextLine for a reason. Moreover, you do not need to pass the value in the argument/ parameter of promptErrorCheckingPercent() method because what you are trying is not allowed in JAVA.
Probably you were thinking passing that variable will help you to store the data in that variable. It is a feature of C-language that supports Pointer (address of the variable) but for the sake of security it is not allowed in JAVA.
You can look into the code below to check if it can solve your problem.
import java.util.Scanner;
public class Test {
public static void main(String[] args) {
Scanner keyboard = new Scanner(System.in);
System.out.println("Please enter the name:");
String sName = keyboard.nextLine();
System.out.print("Please enter the percent achieved for " + sName + ": %");
int iPercent = promptErrorCheckingPercent();
}
public static int promptErrorCheckingPercent() {
Scanner keyboard = new Scanner(System.in);
boolean valid = false;
int test = -1;
while (!valid) {
try {
test = keyboard.nextInt();
valid = true;
} catch(InputMismatchException e) {
System.out.println("Invalid Input. Please enter a valid integer");
return promptErrorCheckingPercent(); // Recursion by calling the method itself
}
}
return test;
}
}
I am having a problem with try and catch. My program is to insert three different strings name, address and phone number then I convert these three in to a single String using toString method.
I have problem with exception handling whenever I write a wrong choice (String or other data type) then catch works infinity times.
import java.util.ArrayList;
import java.util.Scanner;
public class mainClass {
public static void main(String[] args) {
Scanner input= new Scanner(System.in);
ArrayList<String> arraylist= new ArrayList<String>();
CreateFormat FormatObject = new CreateFormat();
int choice;
String phoneNumber;
String name,address;
String format="Empty";
int x=1;
int flag=0;
do
{
try
{
System.out.println("Enter your choice");
System.out.printf("1:Enter new data\n2:Display data");
choice=input.nextInt();
switch (choice)
{
case 1:
{
System.out.println("Enter name ");
name=input.next();
System.out.println("Enter phone number");
phoneNumber=input.next();
System.out.println("Enter address");
address=input.next();
format=FormatObject.toString(phoneNumber, name, address);
arraylist.add(format);
flag++;
}
break;
case 2:
{
System.out.println("Name Phone number Address");
System.out.println();
for(int i=0;i<flag;i++)
{
System.out.println(arraylist.get(i));
}
}
break;
}
}
catch(Exception InputMismatchException){
System.out.println("Enter right choice");`
}while(x==1);
}
}
//The format class ...//returns format for string
Your try and catch are not related to a loop, nor to your problem.
while(x==1)
is what you test on, yet you never change the value of x, so it will always remain 1, and thus the above check will always return true.
I think I now know what your problem actually is.
Simply adding input.nextLine() at the very beginning at your code will stop the input running havoc.
boolean wrongInput = false;
do {
try {
if (wrongInput) {
input.nextLine();
wrongInput = false;
}
System.out.println("Enter your choice");
[...]
} catch (...) {
wrongInput = true;
}
should do the trick. However, please note that I noticed two errors in your program (which might be because I do not have the CreateFormat class of yours), (a) I cannot add a number to the address and (b) there is no option to stop the loop (which I strongly recommend - where you simply set x = -1 or something similar, better use a boolean to end the loop though).
I've copied part of the instructions below, and I can code pretty much every part on its own, but getting the control flow together is giving me massive doubts about my ability.
One of my biggest problems is the int gameChanger. Im supposed to immediately verify if it is a integer or not, and loop back if its not. But then Im also supposed to check to see if thebuser ever types "exit". But the input variable for my scanner instance is an integer... So Im stumped. I can use a try catch to check the missmatchexception once the input is being read in, but that doesnt solve the exit issue nor am I able to come up with solid logic to get the try catch to loop back if it indeed isnt an integer. Im thinking a do while loop but I havent gotten it to work.
Instructions:
You can whether the input is a number before attempting to consume it.
int num;
while (true) {
if (scanner.hasNextInt()) {
num = scanner.nextInt();
break;
} else {
// read whatever is there instead.
String line = scanner.nextLine();
if (line.equals("exit"))
System.exit(0);
System.out.println("Please enter a number");
}
}
System.out.println("Number entered " + num);
This gets the job done. Try it out.
import java.util.Scanner;
public class MyCode
{
public static void main(String[] args)
{
String gameInput = ".";
int gameNumber = 0;
boolean inputLoop = true;
Scanner input = new Scanner(System.in);
while(inputLoop == true)
{
try
{
System.out.print("Please enter a valid game number: ");
gameInput = input.next();
if(gameInput.equals("exit"))
{
System.out.println("Program will now end. Goodbye.");
inputLoop = false;
input.close();
}
gameNumber = Integer.parseInt(gameInput);
if(gameNumber >= 20001 && gameNumber <= 21230)
{
System.out.println("You have inputted a valid game number.");
inputLoop = false;
input.close();
}
}
catch(NumberFormatException e)
{
if(!gameInput.equals("exit"))
{
System.err.println("Invalid game number. Please try again.");
}
}
}
}
}
There are several questions I would like to ask, please refer the comment part I have added in the code, Thanks.
package test;
import java.util.InputMismatchException;
import java.util.Scanner;
public class Test {
/* Task:
prompt user to read two integers and display the sum. prompt user to read the number again if the input is incorrect */
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
boolean accept_a = false;
boolean accept_b = false;
int a;
int b;
while (accept_a == false) {
try {
System.out.print("Input A: ");
a = input.nextInt(); /* 1. Let's enter "abc" to trigger the exception handling part first*/
accept_a = true;
} catch (InputMismatchException ex) {
System.out.println("Input is Wrong");
input.nextLine(); /* 2. I am still not familiar with nextLine() parameter after reading the java manual, would you mind to explain more? All I want to do is "Clear Scanner Buffer" so it wont loop for the println and ask user to input A again, is it a correct way to do it? */
}
}
while (accept_b == false) {
try {
System.out.print("Input B: ");
b = input.nextInt();
accept_b = true;
} catch (InputMismatchException ex) { /*3. Since this is similar to the above situation, is it possible to reuse the try-catch block to handling b (or even more input like c d e...) exception? */
System.out.println("Input is Wrong");
input.nextLine();
}
}
System.out.println("The sum is " + (a + b)); /* 4. Why a & b is not found?*/
}
}
I am still not familiar with nextLine() parameter after reading the java manual, would you mind to explain more? All I want to do is "Clear Scanner Buffer" so it wont loop for the println and ask user to input A again, is it a correct way to do it?
The use of input.nextLine(); after input.nextInt(); is to clear the remaining content from the input stream, as (at least) the new line character is still in the buffer, leaving the contents in the buffer will cause input.nextInt(); to continue throwing an Exception if it's no cleared first
Since this is similar to the above situation, is it possible to reuse the try-catch block to handling b (or even more input like c d e...) exception?
You could, but what happens if input b is wrong? Do you ask the user to re-enter input a? What happens if you have 100 inputs and they get the last one wrong?You'd actually be better off writing a method which did this for, that is, one which prompted the user for a value and returned that value
For example...
public int promptForIntValue(String prompt) {
int value = -1;
boolean accepted = false;
do {
try {
System.out.print(prompt);
value = input.nextInt();
accepted = true;
} catch (InputMismatchException ex) {
System.out.println("Input is Wrong");
input.nextLine();
}
} while (!accepted);
return value;
}
Why a & b is not found?
Because they've not been initialised and the compiler can not be sure that they have a valid value...
Try changing it something more like.
int a = 0;
int b = 0;
Yes, it's okay. And will consume the non-integer input.
Yes. If we extract it to a method.
Because the compiler believes they might not be initialized.
Let's simplify and extract a method,
private static int readInt(String name, Scanner input) {
while (true) {
try {
System.out.printf("Input %s: ", name);
return input.nextInt();
} catch (InputMismatchException ex) {
System.out.printf("Input %s is Wrong%n", input.nextLine());
}
}
}
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int a = readInt("A", input);
int b = readInt("B", input);
System.out.println("The sum is " + (a + b));
}
I have put comment to that question line.
package test;
import java.util.InputMismatchException;
import java.util.Scanner;
public class Test {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
boolean accept_a = false;
boolean accept_b = false;
int a=0;
int b=0;
System.out.print("Input A: ");
while (accept_a == false) {
try {
a = input.nextInt(); // it looks for integer token otherwise exception
accept_a = true;
} catch (InputMismatchException ex) {
System.out.println("Input is Wrong");
input.next(); // Move to next other wise exception // you can use hasNextInt()
}
}
System.out.print("Input B: ");
while (accept_b == false) {
try {
b = input.nextInt();
accept_b = true;
} catch (InputMismatchException ex) {
System.out.println("Input is Wrong");
input.next();
}
}
System.out.println("The sum is " + (a + b)); // complier doesn't know wheather they have initialised or not because of try-catch blocks. so explicitly initialised them.
}
}
Check out this "nextLine() after nextInt()"
and initialize the variable a and b to zero
nextInt() method does not read the last newline character.
Can someone help me make this code neater. I would rather use parse int than a buffer reader. I want my code to loop until the user inputs a number. I couldn't figure out how to do this without the code printing out the same statement twice.
public void setAge()
{
try {
age = Integer.parseInt(scan.nextLine());
} catch (NumberFormatException e) {
System.out.println("What is your age?");
this.setAge();
}
}
Alright, my question is unclear. I am unsure of how to handle the error that a scanner throws when you don't input an integer. How do I handle this? I found "NumberFormatException" in a different post, but I am unsure of what this does. Can anyone help me with this, or is my question still unclear?
Try this:
import java.util.InputMismatchException;
import java.util.Scanner;
public class TestScanner {
public static void main(String[] args) {
Scanner scanner = null;
int age = -1;
do {
try {
scanner = new Scanner(System.in);
System.out.println("What is your age?");
age = scanner.nextInt();
} catch (InputMismatchException e) {
System.out.println("Please enter a number!");
}
} while (age == -1);
System.out.println("You are " + age + " years old.");
if (scanner != null)
scanner.close();
}
}
I get this output (the first time I enter abc instead of a number to make it retry):
What is your age?
abc
Please enter a number!
What is your age?
35
You are 35 years old.
Have fun!
Use scan.nextInt(); instead of scan.nextLine();
With this, you don't need to parse the line.
EDIT: Oops, i misread your question
Number Format Exception occurs in the java code when a programmer tries to convert a String into a number. The Number might be int,float or any java numeric values.
The conversions are done by the functions Integer.parseInt.Consider if you give the value of str is "saurabh", the function call will fail to compile because "saurabh" is not a legal string representation of an int value and NumberFormatException will occurs
You could use a scanner.
You'll need to;
import java.util.*;
static Scanner console = new Scanner(System.in);
You won't need the parse statement at all.
age = console.nextInt();
EDIT: Editing my answer after seeing your edit.
I would put the entire try in a do loop. Using a new boolean variable to control when you come out of it.
boolean excep;
do {
excep = false;
try {
age = console.nextInt();
}
catch (Exception exRef) {
System.out.println("Please input an integer");
console.nextLine();
excep = true;
}
} while (excep);
The console.nextLine() just clears a line so it doesnt re-read the last input. Sometimes it's needed.
Using this i don't receive any error notifications on the running of it.
Try this:
static boolean firstTime = true;
public static void main(String[] args) {
boolean firstTime = true;
setAge();
}
public static void setAge()
{
if(firstTime)
{
System.out.println("What is your age?");
firstTime = false;
}
Scanner scan = new Scanner(System.in);
try{
int age = scan.nextInt();
System.out.println(age);
}
catch(InputMismatchException e)
{
setAge();
}
}
if you want to print different messages you would have to do like:
import java.util.Scanner;
public class Numbers {
public static void main(String args[]) {
Numbers numbers = new Numbers();
numbers.setAge();
}
private boolean alrearyAsked = false;
private int age = 0;
static Scanner scan = new Scanner(System.in);
public void setAge()
{
try {
age = scan.nextInt();
} catch (NumberFormatException e) {
if (alrearyAsked) {
System.out.println("you typed a wrong age, please try again.");
}
else {
System.out.println("What is your age?");
}
this.setAge();
}
}
}