Catch exceptions in a do-while loop? - java

Can someone explain and help me fix this program.
import java.util.*;
import java.io.*;
public class test {
public static void main(String[] args) {
Scanner key = new Scanner(System.in);
boolean clear;
int in = 0;
do {
clear = true;
try {
in = key.nextInt();
} catch (InputMismatchException e) {
System.out.println("Invalid");
clear = false;
}
} while (clear == false);
String stringIn = Integer.toString(in);
String[] dec = stringIn.split("");
for (int i = 1; i < (dec.length); i++) {
System.out.print(dec[i] + " ");
}
}
}
Whenever I enter a invalid input instead of an int, my program keeps looping "Invalid" instead of giving the option to enter a new value for in.

The problem is that if the scanner fails to find an input in the correct format, it will throw an exception and not read the input.
Because the scanner does not read the invalid int input, the next time nextInt is called, it will try to read the invalid input again, and miserably fails at it, printing another "invalid!"
So you need to read the input afterwards if it finds an invalid int:
// do this in the catch block:
key.next();
This makes sure that the next token is read.
Full code:
Scanner key = new Scanner(System.in);
boolean clear;
int in = 0;
do {
clear = true;
try {
in = key.nextInt();
} catch (InputMismatchException e) {
System.out.println("Invalid");
clear = false;
key.next();
}
} while (clear == false);
String stringIn = Integer.toString(in);
String[] dec = stringIn.split("");
for (int i = 1; i < (dec.length); i++) {
System.out.print(dec[i] + " ");
}

Check the API of the nextInt method:
This method will throw InputMismatchException if the next token cannot be translated into a valid int value as described below. If the translation is successful, the scanner advances past the input that matched.
Meaning, that if it's not successful - it will not advance and will try to execute nextInt over the illegal token over and over again failing every time.
Try adding next() into the exception catch clause, it should skip the token and read the next one then. next() reads a String, so it does not really care about the formatting, and will allow you to advance the position in the stream to read the next token.

The problem is that you are writing to the console inside the catch, so then when you call key.nextInt() in the try the program reads the value you print to the console, so an easy way to solve this is to add a line like: key.nextLine() inside the catch and that will solve your problem.

Related

How to correctly use try-catch-finally blocks in Java?

What would be the proper way to use the finally block to close out of the file that I was in : event.dat. If you could help me makes sense of this, I'd greatly appreciate it. I've literally spent 4 hours moving things around, playing with the code and searching for answers online, but to no avail. Code works great without that portion, but I need to know how it works for future instances. Thank you and have a good day!
I am having issues with this block:
finally{
fstream.close();
}
Which is located in the following code:
String answer;
String letter;
String inType = "";
double inAmount = 0;
double amount;
description();
GironEventClass newInput = new GironEventClass();
try{
File infile = new File("event.dat");
Scanner fstream = new Scanner(infile);
System.out.println("File Contents ");
while(fstream.hasNext())
{
inAmount = fstream.nextInt();
inType = fstream.next();
try{
newInput.donations(inType, inAmount);
}
catch(IllegalArgumentException a){
System.out.println("Just caught an illegal argument exception. ");
}
finally{
fstream.close();
}
}
System.out.println("Total Sales: " + newInput.getSale());
System.out.println("Donations: " + newInput.getDonated());
System.out.println("Expenses: " + newInput.getExpenses());
}
catch (FileNotFoundException e){
System.out.println("\nEvent.dat could not be opened. ");
}
do{
System.out.print("Are there any more items to add that were not in the text file? (Type 'Y' or 'N')");
answer = keyboard.next();
if (("Y".equals(answer)) || ("y".equals(answer)))
{
letter = inLetter();
amount = inAmount();
newInput.donations(letter, amount);
}
}while (("Y".equals(answer)) || ("y".equals(answer)));
newInput.display();
}
public static String inLetter(){
Scanner keyboard = new Scanner(System.in);
String result;
String resultTwo;
System.out.println("T = Tiket Sales");
System.out.println("D = Donations");
System.out.println("E = Expenses");
System.out.print("Please input an identifier ");
result = keyboard.nextLine();
resultTwo = result.toUpperCase();
return resultTwo;
}
public static double inAmount(){
Scanner keyboard = new Scanner(System.in);
double result;
System.out.println("Please input an amount ");
result = keyboard.nextInt();
if(result <= 0.0){
System.out.print("Please input a positive and non-zero amount ");
result = keyboard.nextInt();
}
return result;
}
public static void description(){
System.out.println("The program will ask you what amount is being spent on what.");
System.out.println(" ex: expenses, ticket sales, and profts.");
System.out.println("This program will help determine whether the event generated or lost money.");
}
This is how the scanner should work:
while scanner has object
read them ( one object per method's call)
when objects are done
close the reader.
Your problem is that you use the close function when the while conclusion is true. So you should put it outside of the while loop
The Try block attempts to do something.
The Catch block only executes if something went wrong during the Try block.
The Finally block executes after the Try block (and Catch block, if executed) EVERY time.
Your issue is that you attempt to close the fstream inside the while loop.
while(fstream.hasNext()) <----- referencing fstream
{
inAmount = fstream.nextInt();
inType = fstream.next();
try{
newInput.donations(inType, inAmount);
}
catch(IllegalArgumentException a){
System.out.println("Just caught an illegal argument exception. ");
}
finally{
fstream.close(); <---- closing said stream
}
}
Since you've closed the stream, this while loop should only ever execute once. That being said, close the fstream outside the while loop and your program should return to normal.
You can also move the while loop inside the try block, which would work as well.
You need to declare fstream outside the try block otherwise it will be not visible in the finally block.
File infile = null;
File infile = null;
try {
infile = new File("event.dat");
fstream = new Scanner(infile);
...
} catch ( ) {
...
} finally {
// You need to handle exceptions also here
infile.close();
fstream.close();
}
You can also use the new try with resources syntax and leave to the jvm the closure of your streams.

Return to previous spot in loop after try catch?

} 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.

Why do I get a "No line found" Exception in this code?

The following method causes a No line found Exception:
private static String getRebaseAnswer(boolean isFirst, boolean isLast) {
System.out.println("Would you like to (c)ontinue, (s)kip this commit, or"
+ " change this commit's (m)essage?");
Scanner in = new Scanner(System.in);
String answer;
while (true) {
answer = in.nextLine(); // <--- This Line
if (answer.equals("c") || answer.equals("m")) {
in.close();
return answer;
} else if (answer.equals("s") && !isFirst && !isLast) {
in.close();
return answer;
} else {
System.out.println("Would you like to (c)ontinue, (s)kip this commit, or"
+ " change this commit's (m)essage?");
}
}
}
I am calling the method in this method:
...
String answer;
Scanner in;
currHead = branchHeads.get(arg);
while (toRebase != null) {
System.out.println("Currently replaying:");
toRebase.getNode().printInfo();
answer = getRebaseAnswer(isFirst, toRebase.getParent() == null); // <--- This Line
...
What is causing the error?? Shouldn't the scanner wait for me to input a line before continuing the getRebaseAnswer method? A different method in my code has the exact same structure as the above method and encounters no problems. I've checked multiple other posts about this problem but their suggestions are all not pertinent to this problem or do not solve it.
This method runs with no problems:
private static boolean handleDangerous() {
System.out.println("Warning: The command you entered may alter the files in your"
+ " working directory. Uncommitted changes may be lost. Are you sure you"
+ " want to continue? (yes/no)");
Scanner in = new Scanner(System.in);
String answer;
while (true) {
answer = in.nextLine();
if (answer.equals("yes")) {
in.close();
return true;
} else if (answer.equals("no")) {
in.close();
return false;
} else {
System.out.println("Not a valid answer, please enter (yes/no).");
}
}
}
When you create a scanner connected to System.in and close it, you also close System.in. Therefore, subsequent attempts to read from System.in will result in the exception you observe.
The way is avoid this is to create the Scanner only once, and never close it until your program is finished. This Scanner should be passed to whichever function needs to read from System.in.
don't close scanner otherwise Stream will also be closed.
in.close();
remove this line from current location and put it in main method at the end so after all the operation stream will be closed..
You might be calling some other method which have already closed the stream and then you are calling this method.

Java bufferreader crashes on ctrl z

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.

Java reprompt for user input with try... catch

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 ;
}
}
}

Categories

Resources