I want to create a class that will serve me as an exception. I will give you two examples of how I tried. I've been looking for it but I can't find an example of how to put this into practice, or it doesn't work for me.
This is my method where user choose flight by ID, I want to throw an exception if a program user enters a String.
Code:
#Override
public void choosePassenger(ArrayList<Passenger> passengerList) {
System.out.println("Choose passenger by ID: ");
try {
int pickedPassenger = scanner.nextInt();
for (Passenger tempUser : passengerList) {
if (pickedPassenger == tempUser.getId()) {
System.out.println("You picked passenger: " + tempUser.getFirstName() + ", "
+ tempUser.getLastName() + ". Balance is: " + tempUser.getBalance());
selectedPassenger = tempUser;
break;
}
}
} catch (InputMismatchException e) {
System.out.println("Wrong input! Try again");
scanner.nextLine();
}
}
I tried on that way but after program show me message Wrong input! Try again it goes to another method not giving me chance to enter valid input
Also, how I can create exception here for just Strings?
System.out.print("Add name of passenger: ");
passenger.setFirstName(scanner.nextLine());
This is part of code that enable program user to create new user, he is adding here name, I want to create exception so if program user add integer for name I want to show him an exception
EDIT:
If I delete scanner.nextLine(); program stops but first print me my own exception message then print me message from next method and then InputMissMatchException for that method on his own because I input string instead of integer
If you want the user to try again, you can keep them in an infinite loop that breaks after correct input.
Editing as per #DevilsHnd observation. You cannot use scanner.nextInt() in this manner as it will read without user being prompted for input and it results in being stuck in an infinite loop.
You can then use nextLine() and validate the input is a number like this:
while(true) {
try {
int pickedPassenger = Integer.parseInt(scanner.nextLine());
} catch (NumberFormatException e) {
System.out.println("Wrong input! Try again");
}
}
For restricting input to a non numeral value as you want for the name, you would have to check if the value entered is a number (there is no scanner method to restrict reading to non numeral values)
Most elegant way in my opinion is to use an external library that has this like Apache Commons:
while(true) {
String firstName = scanner.nextLine();
if (!NumberUtils.isCreatable(firstName )) {
passenger.setFirstName(firstName );
break;
} else {
System.out.println("Value cannot be a number!");
}
}
However, if you cannot import external libraries, simplest way to do this is by using built in Java Integer.parseInt() function(although you might want to consider regex - see link below):
while(true) {
String firstName = scanner.nextLine();
try {
Integer.parseInt(firstName);
System.out.println("Value cannot be a number!");
} catch (NumberFormatException e) {
passenger.setFirstName();
break;
}
}
For more options on checking if a value is a number (like regex) check this:
https://www.baeldung.com/java-check-string-number
Related
I am trying to learn about "Error handling with Exception " in java.
I know one of the amazing thing about it, is that you can just handle an Exception at one place and it will be caught whenever the exception be thrown in that section, so I have this codes and I want to go back to the while of ReservationManager() after solving the InputMismatchException Exception in catch block in main.
Actually now when a user type string instead of integer in ReservationManager section , the program go back to
Please select: To book or return the room: 1To Exit: 0
but I want to print
Please select: To book a room: 1 To check out: 2 To Exit: 3
Actually I want to go back to ReservationManager after catch block in main.
I have this part of code in a class named hotel:
public static void main(String[] args) {
Hotel hotel = new Hotel(5);
int serviceNumber;
System.out.println("Welcome");
Formatter f = new Formatter(System.out);
Map <Integer, String> whatService = new LinkedHashMap<>(); //list of model services
whatService.put(1,"b.a.service.ReservationManager");
while (true) {
Scanner scanner = new Scanner(System.in);
try {
f.format("%s\n %40s\n %21s\n", "Please select:", "To book or return the room: 1", "To Exit: 0");
serviceNumber = scanner.nextInt();
if(serviceNumber != 0) {
Class c = Class.forName(whatService.get(serviceNumber)); //using RTTI!
c.newInstance();
}
else {
System.exit(0);
}
} catch (NullPointerException e){
System.out.println("---Please Choose from the options!---");
} catch (ClassNotFoundException e) {
System.out.println("ClassNotFoundException");
} catch (IllegalAccessException e) {
System.out.println("IllegalAccessException");
} catch (InstantiationException e) {
System.out.println("InstantiationException");
}catch (InputMismatchException e) {
System.out.println("---Please enter a number!---");
}
}
}
And this part in a class named ReservationManager which will be created if user enter "1" at First.
public ReservationManager() throws Exception{ //constructor
System.out.println("Welcome to reservation section");
int service = 0;
Formatter f = new Formatter(System.out);
while(true){
Scanner scanner2 = new Scanner(System.in);
f.format("%s\n %28s\n %26s\n %21s\n","Please select:","To book a room: 1", "To check out: 2", "To Exit: 3");
service = scanner2.nextInt();
switch (service) {
case 1:
bookingHotelRooms();
break;
case 2:
System.out.println("Please Enter the room number");
checkout(scanner2.nextInt());
break;
case 3:
System.exit(0);
break;
}
}
}
Thanks in advance.
I think, i found my answer. The point is that i made a little mistake, i thought that it is better to handle an Exception just at one single place and should not repeat same try_catch in program, but it isn't correct , Actually unlike it isn't bad to handle same Exceptions at different places in program and it is also helpful to find the exact place of Exception. So i am gonna write a same try-catch in "ReservationManager" and handle "InputMismatchException " in there same as my "main", but it is better to show some information about the exact place (may be by logger).
} else if (selectionKey == 2) {
System.out.println("Please enter the item name");
if (s.nextLine() != "") {
item = s.nextLine();
}
try {
ZybezChecker zb = new ZybezChecker(item);
zb.getAveragePrice();
System.out.println(zb.toString());
} catch(Exception e) {
System.out.println("Something went wrong. Perhaps an invalid item name?");
}
That's my code atm. How do I return back to the if statement and continue the loop after it catches?
You could embed it in a loop like,
for (;;) { // <-- start an infinite loop
System.out.println("Please enter the item name");
if (s.nextLine() != "") {
item = s.nextLine();
}
try {
ZybezChecker zb = new ZybezChecker(item);
zb.getAveragePrice();
System.out.println(zb.toString());
break; // <-- terminate the infinite loop.
} catch(Exception e) {
System.out.println("Something went wrong. Perhaps an "
+ "invalid item name?");
e.printStackTrace(); // <-- tell them what went wrong.
}
}
I think (if I understand your question and code correctly) that what you want is a loop containing the s.nextLine(). Note that I am assuming several things here:
s is a Scanner or something equivalent that reads input from the user
an exception is thrown if the user enters invalid input
you want to keep asking the user for input until they enter something valid
If this is the case, then you should create a loop like this:
while (true) {
System.out.println("Please enter the item name");
if (s.nextLine() != "") {
item = s.nextLine();
}
try {
ZybezChecker zb = new ZybezChecker(item);
zb.getAveragePrice();
System.out.println(zb.toString());
break;
} catch(Exception e) {
System.out.println("Something went wrong. Perhaps an invalid item name?");
}
}
Also, why are you calling nextLine() twice? When you call it the first time, it will read a line from the scanner. When you call it again, it will not return the same line; it will instead wait for a new line. This means the user has to enter some random string, then enter the actual value. Finally, you should NEVER use == or != on Strings. Since they are reference types, you are essentially checking if they occupy the same location in memory, rather than if they are equal. Use s.nextLine().equals("") instead.
I'm making a game which plays until the user enters quit in the command line.
The user can enter different commands like get and go, with the get command the user can say what to get like, get baseball bat. What I do in my code is split the command.
everything is working fine but I have found a bug which I can't solve. If I enter "get" and press space and then ctrl+z it gets in a while loop which never ends.
It only happens with ctrl+z (1 time with ctrl c but after that 1 time not anymore)
private void run()
{
while (! quitCommand)
{
String input = null;
try
{
input = null;
System.out.println("Input "+ input);
System.out.println("Give a command.");
BufferedReader is = new BufferedReader(new InputStreamReader(System.in));
input = is.readLine();
handleCommand(input);
// As long as the command isn’t to quit:
// get the next input line and handle it. (With handleCommand.)
}
catch (Exception e)
{
System.out.println("Something went wrong we are sorry try again.");
e.printStackTrace();
}
}
}
/**
* #param userInput (This is the entire input string from the user.)
*
* (Tell others to) Perform the task which belongs to the given
* command.
*/
private void handleCommand(String userInput)
{
// Split the user input string.
if (userInput != null) // user input can not be empty
{
String[] delenTekst = userInput.split(" ");
// The first word is a command. The rest is extra information
String command = delenTekst[0];
String extra = "";
for (int i = 1; i < delenTekst.length; i ++)
{
if (i == 1)
{
extra = extra + delenTekst[i];
}
else
{
extra = extra +" " + delenTekst[i];
}
}
switch (command)
{
// Check if the command is to travel between rooms. If so, handle
case "go"
:
this.checkRoomTravel(extra);
break;
// If there isn't any room travel, then check all other command
case "get"
:
System.out.println("Looking for " +extra );
this.handleGetCommand(extra);
break;
case "quit"
:
quitCommand = true;
break;
default
:
System.out.println("Command is not known try help for information");
break;
}
}
else
{
userInput = "help";
}
}
I'm new to java so it can be something really simple.
On the top of my script I have a private boolean quitCommand = false; which is to check if the user entered quit.
Ctrl+Z closes the Console and therefore your readLine() returns null as pretended to indicate that end of file was reached. So all you need to do, is to check for null returned by readLine() and handle this as you handle the "quit".
I've changed your code (just to test my thesis) and also stream lined a few things, e.g. you dont need to recreate a BufferedReader every time you read a line.
private boolean quitCommand = false;
private void runIt() {
BufferedReader is = new BufferedReader(new InputStreamReader(System.in));
String input = null;
while(!quitCommand) {
try {
System.out.print("Give a command: ");
input = is.readLine();
// As long as the command isn’t to quit:
if(input == null || "quit".equals(input.trim())) quitCommand = true;
if(quitCommand) break;
// get the next input line and handle it. (With handleCommand.)
String[] words = input.trim().split("\\s+");
// ** This is the original handleCommand line **
System.out.println(input + ":" + Arrays.toString(words));
}
catch (Exception e) {
System.out.println("Something went wrong we are sorry try again.");
e.printStackTrace();
}
}
}
BTW: To split the input into words I'd use the regular expression as shown in my code. This works also if the user enters tabs or multiple spaces.
On DOS/Windows Ctrl+Z means end of input. This causes readLine() to return null no matter how many times you call it. This is likely to cause your code to fail as you don't appear to check for it. I suspect you are getting a NullPointerException which you are pretending didn't happen and trying again, endlessly.
So if a user puts in a postfix value like say 453-* , my method EvalPostFix() does the work, but when the user inputs something invalid like 43*+ or any invalid string want the program to repromt the user for input dont know how to implement with try catch..
'
String in;
while(true){
System.out.println("Please enter the numbers first followed by the operators, make sure to have one less operator than of numbers");
try {
in = getString();
int result = EvalPostFix(in);
System.out.println(result);
} catch (IOException e) {
// TODO Auto-generated catch block
String s = "Not a valid postfix string";
e.toString();
in = getString();
}
}
'
Looking at your code I think you just need to get rid of the in = getString(); in the catch block and add an break at the end of the try block.
I don't recommend using a while(true) or an IOException for what you are doing though, but that should get your code working.
Use a flag:
boolean flag = false;
while(!flag)
{
//make the loop break, if no exception caught
flag = true;
try{
}
catch{
//make the loop repeat
flag = false;
}
}
this should repeat the prompt every time you catch an exception. you can also use this to validate input.
how the flag is oriented depends on your preference. I like to flag true when an error occured ;)
this will also break your while loop, as soon as you get a valid input.
Something like this is can be used to get an input of desired specifications
public static void userMove() {
System.out.println("Where would you like to move? (R, L, U, D)\n");
Scanner input = new Scanner(System.in) ;
while (true){
String userInput = input.next() ;
if(userInput.length()>1){
System.out.println("Please input a valid direction");
}else{
break ;
}
}
}
I am a newbie. I know that my code is messy. I will be working on adding the comments and such.
try // get customer's address
{
System.out.println("\nPlease type in your shipping address.");
System.out.println ("This way you can receive what you have ordered.");
System.out.println ("In this format: Street, City, State, Zipcode\n");
customerAddress = input.nextLine();
}
catch (Exception e)
{
System.out.println("You need to enter in an address.");
}
try // get customer's telephone number
{
System.out.println("Please enter in your telephone number:\n");
phoneNumber = input.nextLine();
}
catch (Exception e)
{
System.out.println("You need to enter in a phone number.");
}
I am able to get an input from the phoneNumber but the program seems to skip right over the customerAddress input.
Below is what I get in the command prompt. Notice that I was able to input data under the telephone number, but did not get the chance to put it in the address section.
Please type in your shipping address.
This way you can receive what you have ordered.
In this format: Street, City, State, Zipcode
Please enter in your telephone number:
123457890
Are there any logic errors that could be causing it to skip over?
If you are reading more data, with Scaner like input.nextInt(); then it will read only one int.
One solution is that add input.nextLine(); and it should probably work.
Solution 2:
Use BufferedReader;
BufferedReader bufferRead = new BufferedReader(new InputStreamReader(System.in));
try{
System.out.println("\nPlease type in your shipping address.");
System.out.println ("This way you can receive what you have ordered.");
System.out.println ("In this format: Street, City, State, Zipcode\n");
customerAddress = bufferRead.readLine();
}catch (Exception e){
System.out.println("You need to enter in an address.");
}
try {
System.out.println("Please enter in your telephone number:\n");
phoneNumber = bufferRead.readLine();
}catch (Exception e){
System.out.println("You need to enter in a phone number.");
}
System.out.println(customerAddress + " " + phoneNumber);
See if you get the output with the BufferedReader.
Hope this helps.
Any number of other things that weren't shown in your post could be causing a stray new line to remain on the buffer. A more robust option is to loop while nextLine returns an empty string.