I am trying to terminate a program if the if statement returns that the file does not exist. At the moment the method is
public static void calcMarks()
{
String Assessment1 = null, Assessment2 = null, Assessment3 = null;
int mark1 = 0,mark2 = 0,mark3 = 0,sum = 0;
try {
File doc = new File ("marks.txt");
if(!doc.exists())
{
System.out.println ("Marks.txt Does Not Exist");
System.exit();
}
if(!marks.exists())
{
System.out.println ("TotalMarks.txt Does Not Exist");
System.exit();
}
Scanner input = new Scanner(doc);
while (input.hasNext()){
Assessment1 = input.next();
mark1 = input.nextInt();
Assessment2 = input.next();
mark2 = input.nextInt();
Assessment3 = input.next();
mark3 = input.nextInt();
}
input.close();
sum = mark1 + mark2 + mark3;
System.out.println(Assessment1 + " " +mark1 +"\n"+ Assessment2 + " "+mark2 +"\n"+ Assessment3 + " "+mark3+ "\n" + "Total" +""+ "=" + sum);
}
catch (FileNotFoundException ex) {
System.err.println("File has not been found");
}
}
but on the System.exit(); is the if statement, I get the error exit(int) in Jaba.lang.system. cannot be applied to ()
I have no idea what that means
You need to pass the return value in the exit() method.
Optimally, you should have System.exit( 0 );.
You can read this.
You must pass a status code (as an integer) to the System.exit() method. There is no argument-less version of this method.
The method's documentation:
Terminates the currently running Java Virtual Machine. The argument serves as a status code; by convention, a nonzero status code indicates abnormal termination.
This method calls the exit method in class Runtime. This method never returns normally.
Parameters: status - exit status.
You need to pass a return code to exit. Have a look at the documentation for java.lang.System. System.exit(-1); should work.
you need to enter an integer as a parameter for System.exit.
System.exit(0);
or
System.exit(1);
I'm not a Java programmer, but it looks to me like System.exit() should have an exit code. Try this:
System.exit(0);
System.exit(int) requires an integer argument:
System.exit(1);
The operating system is expecting an Exit Status to report to the program that spawned your program.
A further nitpick: you are looping over input, storing it into variables, and then doing nothing with those variables until the end of your loop. You will throw away all but the last input to your routine. So when you go looking for that bug, you'll know where to look. :)
If I remember right with java an argument must be passed to. This serves as a debugging tool so you can easily tell what part forced the program to exit. without having to print anything out. Generally one would use 0 for any successful exit and any other predetermined values by the programmer as an "error code." So without any further explination you would want to change your exit call to something like the following:
System.exit(0); //This would be for a programming successfully running and exiting.
or
System.exit(X); //Where x is any int to signal a program failure
Related
Language: Java, IDE: eclipse mars
The program is supposed to prompt the user (using JOptionPane) for a positive value. I'm trying to catch the invalid entries. My while statement catches the negative numbers but not the strings. When a negative number is entered, the prompt is shown again, but when a string value is entered, the exception is caught and the program moves on (when it should re prompt the user).
Once a positive value has been entered, the program assigns it to a value in another class. (We're learning the MVC OOP design pattern).
Double.isNaN(Double.parseDouble(h)) ---> can anyone help me find what am I missing?
// prompt to get bandwidth from user
// check for validity
// if invalid, prompt again
try{
h = JOptionPane.showInputDialog("Enter bandwidth as a positive number");
// loop until parsed string is a valid double
while (Double.isNaN(Double.parseDouble(h)) || Double.parseDouble(h) <=0) {
h = JOptionPane.showInputDialog("Enter bandwidth as a positive number");
}
// h has been set to valid double, set it to bandwidth
model.setBandwidth(Double.parseDouble(h));
}catch(NumberFormatException|NullPointerException NFE){
System.err.println("Caught exception: " + NFE.getMessage());
}
This is because of how parseDouble() works.
Throws:
NumberFormatException - if the string does not contain a parsable double.
(See here)
So if the String is not a double parseDouble() will not return NaN but throw an exception, which means your catch clause will be called.
To solve this problem maybe use recursively algorithm which will call your method again if an exception is thrown.
As 4castle already stated, you need to move your try/catch block inside your while loop.
However, for validating user input you can basically stick to the following pattern:
public Foo getUserInput() {
Foo result;
do {
try {
String s = requestUserInput(); // something like Scanner.nextLine()
result = parseUserInput(s); // something like Double.parseDouble(String)
}
catch(Exception exc) {
// maybe you want to tell the user what's happened here, too
continue;
}
}
while(!isValid(result)); // something like (0 < result)
return result;
}
Snippet of the code
while(!((input = sc.nextLine()) != null)) {
sc = new Scanner(input).useDelimiter(" ");
while (sc.hasNextLine()) {
in[index] = sc.next();
index++;
}
if (index < 3 || !in[0].equals("ping")) {
throw new IllegalArgumentException(
"Usage ping <destination> <port number missing> . . . ."
+ in[0] + " " + in[1] + " " + in[2]);
}
}
I want to keep reading user inputs but after the first iteration, i get no new line found. Scanner does not wait for the user input but rather advances on.
Thanks
Your top-level while loop is doing the opposite of what you want. First it sets input equal to sc.nextLine(), which is good. Then input is compared to null. If this comparison yields true, then you have input, which means that the loop should continue. However, you are then negating the result of that comparison, which makes the loop terminate when there is input.
Remove the exclamation point, and you should be good.
EDIT
On second thought, your inner while loop is exiting when sc.hasNextLine() returns false. After that, you will go through the conditional statement and return to the top. Since sc.hasNextLine() already returned false, of course sc.nextLine() will return null. The input has already ended in the inner loop, so the outer loop will exit as well.
This question already has answers here:
How do I exit a while loop in Java?
(10 answers)
Closed 5 years ago.
I am new to Java and programming in general. I've encountered not exactly a problem, but more like a wall of my ignorance. On my QA Automation courses I was asked to write a simple calculator program in Java, I kept it very basic - you needed to launch the program over again every time you preformed a calculation. I learned about while loops and it seemed the while loop was a good solution to keep the program running. But now I am at another extreme - the loop is infinite. My question is: is there any simple way to exit the program without re-writing the code and the way I've structured my calculator? I don't know how to do it but it would be nice if program would end when user presses [Esc] or prints "Exit". Is there a simple way that I (beginner) would understand and could implement?
import java.io.IOException;
import java.util.Scanner;
public class Calculator {
public static void main(String[] args) {
int first, second, answer;
String operator;
Scanner s = new Scanner(System.in);
try {
while (true) {
log("Please enter a math equation using +, -, * or /");
first = s.nextInt(); //User enters first number
operator = s.next(); //User enters operator
second = s.nextInt(); //User enters second number
if (operator.contains("+")) {
answer = first + second;
log("" + answer);
}
if (operator.contains("-")) {
answer = first - second;
log("" + answer);
}
if (operator.contains("*")) {
answer = first * second;
log("" + answer);
}
if (operator.contains("/")) {
if (second == 0) {
log("You can't divide by 0");
} else {
answer = first / second;
log("" + answer);
}
}
}
} catch (java.util.InputMismatchException error) {
log("Incorrect input");
}
}
public static void log(String s) {
System.out.println(s);
}
}
Thank you, if you can help me!
P.S. I don't know if it is a correct way to handle exceptions or a very ugly one. I'd appreciate if you could comment on that too.
Yes, use break:
if(endingCondition)
break;
This will break out of the innermost loop.
In order to follow your example and not deviate from it focusing on other code improvements, you should have to change the way you read the parameters, because the way you do it now, you could never read the exit word to get out. In order to do this you can use the following approach:
This will add a new string parameter to read the exit or the first operand (in string format). Then, it will transform it into an int:
int first, second, answer = 0;
String operator, firstParam = "";
Scanner s = new Scanner(System.in);
try {
while (true) {
System.out.println("Please enter a math equation using +, -, * or /, or exit if you want to stop the program");
firstParam = s.next(); //User enters first number or exit
// This first param is read as a String so that we are able to read the word exit
if(firstParam.equals("exit"))
break;
first = Integer.valueOf(firstParam); // This will transform the first parameter to integer, because if it reaches this point, firstParam won't be "exit"
//[... Rest of your program...]
}
} catch (java.util.InputMismatchException error) { ... }
TIPS FOR ERROR HANDLING
1: You don't have to specify the complete reference of the InputMismatchException while in catch block because you have already imported the java.util package
catch (InputMismatchException e)
{
//handle exception here
}
2: In case you are unsure about the type of Exception that can thrown, just catch the object of class Exception. Since Exception is the super class for all the Exceptions, it can handle all exceptions.. This would work perfectly for beginners.
catch (Exception e)
{
//handle exception
}
3: You can handle multiple exceptions for the same try block, each catch handling a particular type of exception. Give it a try.
FOR EXITING THE LOOP
if (s1.contains("EXIT"))
break;
Here s1 is the string, and if the string contains the word EXIT (ALL CAPS ONLY), the loop will terminate.
I am calling this method and it works perfectly for the most part. Not sure if this is enough code for you guys to extrapolate from and figure out my problem, but I guess I will give it a shot..
When I enter an integer that is out of the bounds of the array or the file name does not exist, it throws the catch statement. I want it to then loop back to the question that the program is asking and not just continue to the rest of the program.. I keep getting an error when I throw the catch statement in the same while loop as the try statement. Thanks for the help, and I hope that was clear enough for you guys to understand.
public static String [][] placeCustomer(String [][] MovieSeats, int rows, int columns, String database)
{
//Get user data and then write the name to the array space specified by the user..
Scanner input = new Scanner(System.in);
try
{
File readFile = new File(database);
Scanner reader = new Scanner(readFile);
while (reader.hasNextLine())
{
String user = reader.nextLine();
System.out.println(user + " wants to sit in the theater. Where would you like to place him?");
String lastUser = user;
System.out.print("Row: ");
int placeRow = input.nextInt();
System.out.print("Column: ");
int placeCol = input.nextInt();
while (!MovieSeats[placeRow][placeCol].equals("Seat Empty |")) //If element in 2-D array reads empty, then tell user.
{
System.out.println("Sorry that seat is already taken.. try a different location.."); //Give them another chance to change location
System.out.println("Please enter a new location for " + user);
System.out.print("Row: ");
placeRow = input.nextInt();
System.out.print("Column: ");
placeCol = input.nextInt();
if (MovieSeats[placeRow][placeCol].equals("Seat Empty |")) //If it is empty, allow user to fill the 2-D element..
{
break;
}
}
if (MovieSeats[placeRow][placeCol].equals("Seat Empty |"))
{
while (MovieSeats[placeRow][placeCol].equals("Seat Empty |"))
{
System.out.println("The customer " + user + " has been placed at row " + placeRow + " and the column " + placeCol + ".");
System.out.println();
MovieSeats[placeRow][placeCol] = user;
System.out.println("The current seating \n________________________");
viewFilledTheater(MovieSeats, rows, columns);
System.out.println();
}
}
else
{
System.out.println("Please enter a valid value for the program to understand where you would like to place the customer...");
}
}
}
//If the file does not exist, then catch the exception, print this statement and exit the program..
catch (FileNotFoundException e)
{
System.out.println("The movie theater will remain empty because \nwe cannot find the customer list with the name you provided..");
}
catch (ArrayIndexOutOfBoundsException e)
{
System.out.println("I am sorry, but the integer you entered is not within the proper bounds of the theater..");
}
return MovieSeats;
while, I have a detailed look at your code, I think you can just make it more simple. You want ArrayIndexOutOfBoundsException to be catched and then terminal re-ask the client to input the placeRow, placeCol, so, you should put the ArrayIndexOutOfBoundsException catch clause inside the while loop, while put the FileNotFoundException catch clause outside the while loop.
Below is a simple demo on how to put the ArrayIndexOutOfBoundsException try-catch clause to meet you need
while(true){
System.out.println(user
+ " wants to sit in the theater. Where would you like to place him?");
String lastUser = user;
System.out.print("Row: ");
int placeRow = input.nextInt();
System.out.print("Column: ");
int placeCol = input.nextInt();
try{
if(!MovieSeats[placeRow][placeCol].equals("Seat Empty |")){
System.out.println("Sorry that seat is already taken.. try a different location..");
System.out.println("Please enter a new location for "+ user);
continue;
}else{
//set this seat occupied
break;
}
}catch(ArrayIndexOutOfBoundsException e){
//e.printStackTrace();
continue;
}
}
So, first off, you throw Exceptions, which are caught by catch statements (that's why they call them catch statements). Your problem is really just one of scoping. Nest your try/catch inside the relevant loop. Note that after an exception, the program resumes after the catch block(s). If needed, you can have multiple nested try/catch statements.
You should build a recursive method that does this:
step 1. check if the seats are available. If the seats are available, then place the user and display.
step 2. if the seats are not available, ask the user to see if the user likes to re-enter their choice. If YES, go to step 1. If NO, exit.
that way no matter how many times the user chooses the wrong values, he will always be given a choice to re-enter. Your program will never exit until the user chooses to.
I hope this gives you some idea. Good Luck.
I am using the following code:
while (invalidInput)
{
// ask the user to specify a number to update the times by
System.out.print("Specify an integer between 0 and 5: ");
if (in.hasNextInt())
{
// get the update value
updateValue = in.nextInt();
// check to see if it was within range
if (updateValue >= 0 && updateValue <= 5)
{
invalidInput = false;
}
else
{
System.out.println("You have not entered a number between 0 and 5. Try again.");
}
} else
{
System.out.println("You have entered an invalid input. Try again.");
}
}
However, if I enter a 'w' it will tell me "You have entered invalid input. Try Again." and then it will go into an infinite loop showing the text "Specify an integer between 0 and 5: You have entered an invalid input. Try again."
Why is this happening? Isn't the program supposed to wait for the user to input and press enter each time it reaches the statement:
if (in.hasNextInt())
In your last else block, you need to clear the 'w' or other invalid input from the Scanner. You can do this by calling next() on the Scanner and ignoring its return value to throw away that invalid input, as follows:
else
{
System.out.println("You have entered an invalid input. Try again.");
in.next();
}
The problem was that you did not advance the Scanner past the problematic input. From hasNextInt() documentation:
Returns true if the next token in this scanner's input can be interpreted as an int value in the default radix using the nextInt() method. The scanner does not advance past any input.
This is true of all hasNextXXX() methods: they return true or false, without advancing the Scanner.
Here's a snippet to illustrate the problem:
String input = "1 2 3 oops 4 5 6";
Scanner sc = new Scanner(input);
while (sc.hasNext()) {
if (sc.hasNextInt()) {
int num = sc.nextInt();
System.out.println("Got " + num);
} else {
System.out.println("int, please!");
//sc.next(); // uncomment to fix!
}
}
You will find that this program will go into an infinite loop, asking int, please! repeatedly.
If you uncomment the sc.next() statement, then it will make the Scanner go past the token that fails hasNextInt(). The program would then print:
Got 1
Got 2
Got 3
int, please!
Got 4
Got 5
Got 6
The fact that a failed hasNextXXX() check doesn't skip the input is intentional: it allows you to perform additional checks on that token if necessary. Here's an example to illustrate:
String input = " 1 true foo 2 false bar 3 ";
Scanner sc = new Scanner(input);
while (sc.hasNext()) {
if (sc.hasNextInt()) {
System.out.println("(int) " + sc.nextInt());
} else if (sc.hasNextBoolean()) {
System.out.println("(boolean) " + sc.nextBoolean());
} else {
System.out.println(sc.next());
}
}
If you run this program, it will output the following:
(int) 1
(boolean) true
foo
(int) 2
(boolean) false
bar
(int) 3
This statement by Ben S. about the non-blocking call is false:
Also, hasNextInt() does not block. It's the non-blocking check to see if a future next call could get input without blocking.
...although I do recognize that the documentation can easily be misread to give this opinion, and the name itself implies it is to be used for this purpose. The relevant quote, with emphasis added:
The next() and hasNext() methods and their primitive-type companion methods (such as nextInt() and hasNextInt()) first skip any input that matches the delimiter pattern, and then attempt to return the next token. Both hasNext and next methods may block waiting for further input. Whether a hasNext method blocks has no connection to whether or not its associated next method will block.
It is a subtle point, to be sure. Either saying "Both the hasNext and next methods", or "Both hasnext() and next()" would have implied that the companion methods would act differently. But seeing as they conform to the same naming convention (and the documentation, of course), it's reasonable to expect they act the same, and hasNext()
clearly says that it can block.
Meta note: this should probably be a comment to the incorrect post, but it seems that as a new user I can only post this answer (or edit the wiki which seems to be preferred for sytlistic changes, not those of substance).
Flag variables are too error prone to use. Use explicit loop control with comments instead. Also, hasNextInt() does not block. It's the non-blocking check to see if a future next call could get input without blocking. If you want to block, use the nextInt() method.
// Scanner that will read the integer
final Scanner in = new Scanner(System.in);
int inputInt;
do { // Loop until we have correct input
System.out.print("Specify an integer between 0 and 5: ");
try {
inputInt = in.nextInt(); // Blocks for user input
if (inputInt >= 0 && inputInt <= 5) {
break; // Got valid input, stop looping
} else {
System.out.println("You have not entered a number between 0 and 5. Try again.");
continue; // restart loop, wrong number
}
} catch (final InputMismatchException e) {
System.out.println("You have entered an invalid input. Try again.");
in.next(); // discard non-int input
continue; // restart loop, didn't get an integer input
}
} while (true);