In my code below im am tring to add a thread.sleep for when someone chooses the option to exit the lift, i am not sure whats wrong with the code i entered to make it sleep.I already included the Interrupted exception so can someone tell me where i went wrong.
import java.util.Arrays;
import java.util.Scanner;
public class username{
public static void main(String... args) throws InterruptedException {
String[] verifiedNames = { "barry", "matty", "olly", "joey" };
System.out.println("choose an option");
System.out.println("Uselift(1)");
System.out.println("see audit report(2)");
System.out.println("Exit Lift(3)");
Scanner scanner = new Scanner(System.in);
int choice = scanner.nextInt();
switch (choice) {
case 1:
scanner.nextLine(); // get '\n' symbol from previous input
int nameAttemptsLeft = 3;
while (nameAttemptsLeft-- > 0) {
System.out.println(" Enter your name ");
String name = scanner.nextLine();
if (Arrays.asList(verifiedNames).contains(name)) {
System.out.println("dear " + name + " you are verified " +
"you may use the lift, calling lift ");
break; // break out of loop
}
}
if (nameAttemptsLeft < 0) {
System.out.println("Username Invalid");
}
break;
case 2:
System.out.println("option 2");
break;
case 3:
System.out.println(" Please Exit Lift ");
Thread.sleep(5000);
System.exit(0);
break;
}
You're ending your program after the sleep returns.
Thread.sleep(5000);
System.exit(0);
Maybe you're looking for a loop of some kind. You haven't shown us what comes after the switch, but maybe that System.exit(0), which stops the java process, shouldn't be there.
Get rid of the System.exit(0)
Wrap your method in a loop if you want it to loop. My example is an infinite loop, but if your application accepts user input you can just as easily have a boolean flag that serves as the loop condition.
public static void main(String... args) throws InterruptedException {
while(true){
//all of your code
}
}
Also you should surround your sleep in a try-catch instead of declaring a throws on your main method... it is good practice to catch exceptions you can handle, and throw exceptions that you cannot handle to earlier stack frames that can. Typically you don't want your main() method to have a throws clause as it can cause the premature termination of your application. This doesn't really matter for InterruptedException in your specific case, but does for many other exceptions.
Related
I am a beginner at java and I want to loop this all over again but I don't know how. I've tried a while loop but it doesn't work really well and it prints both blocks of code. What should happen is when I type "quit, Quit, or QUIT", it should terminate. What happens instead is that it also prints the message "failed to terminate the program". What should I do? I've also tried an if statement which works fine but I don't know how to loop it if the condition fails.
import java.util.Scanner;
public class fortytwo {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("Hi there!");
String quit = scanner.next();
while (quit.equals("quit") || quit.equals("QUIT") || quit.equals("Quit")) {
System.out.println("You terminated the program");
break;
}
System.out.println("You failed to terminate the program.\n To quit, type (quit), (Quit), or (QUIT)");
scanner.close();
}
}
You are using a loop without a need for it. Also break only exits the loop, but continues execution after the loop. Replace the while with an if/else:
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("Hi there!");
String quit = scanner.next();
if(quit.toLowerCase().equals("quit")) {
System.out.println("You terminated the program");
} else {
System.out.println("You failed to terminate the program.\n To quit, type (quit), (Quit), or (QUIT)");
}
scanner.close();
}
This does not prompt for input again which your second output hints at, but neither does your code.
The condition of the loop is to check while quit is NOT equal to "quit" (regardless of the case), so the message "You failed to terminate the program..." should be printed in the loop body until appropriate command is entered.
Also, assignment to quit may be omitted, and the method equalsIgnoreCase is recommended to invoke on the constant/literal value because in general case it helps avoid NullPointerException.
while (!"quit".equalsIgnoreCase(scanner.next())) {
System.out.println("You failed to terminate the program.\n To quit, type (quit), (Quit), or (QUIT)");
}
System.out.println("You terminated the program");
I have a homework assignment to create a class with a looping menu to manage a queue of cars. We learned queues in our last class.
My menu works perfectly fine until it catches InputMismatchException or QueueEmptyException, after which it goes into endless loop, not even stopping at the userInput.nextInt();. It works when it catches QueueFullException, but not the others.
My code is:
import java.util.*;
public class CarQueueManagement {
public static void main(String[] args) throws InputMismatchException, QueueFullException{
ArrayQueue queue = new ArrayQueue(3);;
Scanner userInput = new Scanner(System.in);
int carNum;
int choice = 0;
queue.add(1);
OUTER:
while (true) {
try{
System.out.println("ΜΕΝΟΥ:\n\t1. Άφιξη αυτοκινήτου");
System.out.println("\t2. Αναχώρηση αυτοκινήτου\n\t3. Κατάσταση ουράς\n\t4. Έξοδος");
System.out.print("\n\tΕπιλογή (1-4): ");
choice = userInput.nextInt();
switch (choice){
case 1:
System.out.print("\n\tΆφιξη αυτοκινήτου:\n\t\tΑριθμός Αμαξιού");
carNum = userInput.nextInt();
queue.add(carNum);
break;
case 2:
if(queue.isEmpty()){
System.out.println("\n\tΗ ουρά είναι άδεια, δεν χριάζεται διαγραφή.\n\n");
break;
}
String answer;
while(true){
System.out.print("\n\tΑναχώρηση αυτοκινήτου\n\t\tΕπιβεβαίωση; (y/n): ");
answer = userInput.next();
if(answer.equals("y")){
queue.remove();
break;
}
else if(answer.equals("n"))
break;
}
break;
case 3:
System.out.println("\n\tΚατάσταση ουράς:");
if(queue.isEmpty()) System.out.println("\t\tΗ ουρά είναι άδεια.\n\n");
else if(queue.isFull()) System.out.println("\t\tΗ ουρά είναι γεμάτη.\n\n");
else System.out.println("\t\tΗ ουρά έχει άδιες θέσοις.\n\n");
break;
case 4:
System.out.print("\n\nΕξοδος");
break OUTER;
default:
break;
}
}catch (InputMismatchException exc){
System.out.println("\t\tΛΑΘΟΣ ΕΙΣΑΓΩΓΗ\n");
}catch(QueueEmptyException exc){
System.out.println("\t\t" + exc.getMessage() + "\n");
}catch(QueueFullException exc){
System.out.println("\t\t" + exc.getMessage() + "\n");
}
}
}
}
From the intro section of java.util.Scanner docs (emphasis mine):
When a scanner throws an InputMismatchException, the scanner will not pass the token that caused the exception, so that it may be retrieved or skipped via some other method.
Without the details, your while(true) loop is:
while (true) {
try{
choice = userInput.nextInt();
switch (choice){
case 1:
...
}
} catch (InputMismatchException exc){
// Do nothing.
}
}
When the user enters something that can't be converted to an integer, the Scanner throws an InputMismatchException, which you catch and ignore. Then the while loop goes back to the top, where it tries to execute userInput.nextInt()... but the Scanner is still looking at the same invalid input, so it immediately throws another InputMismatchException, which you catch and ignore again. Execution continues at the top of the while loop, where it calls nextInt() again... and the cycle continues forever.
You have to force the Scanner to skip the bad input, so your catch block should look something like this:
}catch (InputMismatchException exc){
System.out.println("\t\t[chastise the user in Greek]\n");
userInput.next(); // Skip invalid input.
}
Other Advice
As a general rule, lots of small methods are easier to understand than one large method. The nested while loops and switch statement were especially hard to follow. I was only able to find the bug by breaking that gigantic main method into many smaller, private static methods.
At the very least, each menu item could be handled in its own method. I also got rid of the break label by putting the whole menu into a separate method, which returned a boolean indicating whether the user was done or not. That reduced the whole loop inside main to:
boolean done = false;
while (! done) {
try{
done = handleUserInput(queue, userInput);
} catch (InputMismatchException exc) {
System.out.println("\nINPUT ERROR\n");
userInput.next();
} // Other catch blocks as before...
}
My handleUserInput doesn't do much --- it gets user input, determines which method should handle that input, and then returns true or false... It could be made simpler than this, too.
private static boolean handleUserInput(
final ArrayQueue queue,
final Scanner userInput
) {
boolean done = false;
printMenu();
int choice = userInput.nextInt();
switch (choice) {
case 1:
addToQueue(queue, userInput);
break;
case 2:
removeFromQueue(queue, userInput);
break;
case 3:
displayQueue(queue);
break;
case 4:
printExitMessage();
done = true;
break;
default:
break;
}
return done;
}
Splitting the various menu activities into separate methods made them much easier to follow. For example, when the logic was all mixed together in main, it was hard to tell if variables like carNum or answer were part of the problem. In this version, carNum is a local variable trapped inside the addToQueue method, so when I'm working anywhere else, I can completely ignore it.
I have some code that involves checking user input to see if it the input entered is a string or an int, and will execute different code depending on the result. I am using Integer.parseInt in order to determine if the user input is an integer or not, with the NumberFormatException being thrown if it is not.
However, in order to control the flow of the code, i am using a try/catch statement, with the catch block being used to contain code that will be run if the user's input is a string (i.e NumberFormatException) is thrown.
Qn
Is this an acceptable way of using the try/catch block? I've try googling this but all i could find were examples of the catch block being used to handle the Exception thrown instead of it being used as i am doing.
import java.io.*;
import java.util.*;
public class Datafile{
private static Scanner input = new Scanner(System.in);
public static void main(String[] args) throws IOException {
BufferedWriter bw = new BufferedWriter(new FileWriter("C:\\Users\\Kence\\workspace\\Java 8 - Beyond the Basics - Working Files\\Practice Programs\\src\\Practice Data Edited",true));
String data = null;
boolean end = false;
boolean cont = true;
String dataEntered = null;
int menuChoice = printMenu();
while(!end){
switch(menuChoice){
case 1:
System.out.println("Please enter a line of data or press 0 to exit back to the main menu");
dataEntered = input.nextLine();
try {
if(Integer.parseInt(dataEntered) == 0){
break;
}
} catch (Exception e) {
data += dataEntered + "\n";
while(cont){
System.out.println("Data entered.Please enter the next line of data or press quit to exit back to the main menu.");
dataEntered = input.nextLine();
if(Integer.parseInt(dataEntered) == 0){
cont = false;
break;
}else{
data+= dataEntered;
System.out.println("Current data entered is " + dataEntered);
}
}
}
break;
case 2:
System.out.println("2 Entered");
break;
case 3:
System.out.println("3 Entered");
break;
case 4:
System.out.println("4 Entered");
break;
}//End of switch statement
menuChoice = printMenu();
}
input.close();
}//End of main
public static void printStars(){
for(int i = 0; i<66 ; i++){
System.out.print("*");
}
System.out.println();
}
public static int printMenu(){
printStars();
System.out.println("System Started");
printStars();
System.out.println("Enter 1 to input a new line of data");
System.out.println("Enter 2 to list all data");
System.out.println("Enter 3 to save existing data");
System.out.println("Enter 4 to load data");
printStars();
return Integer.parseInt(input.nextLine());
}
}
It isn't considered best practices to use a try/catch block for control flow, but it is "acceptable" if you don't care about best practices.
See Determine if a String is an Integer in Java for examples of other ways to check if a number is an integer. You could use one of those examples and then if it is an integer check if it's equal to zero.
Also, in your code it appears your second call to Integer.parseInt(dataEntered) could still throw an exception that would not be caught.
Exceptions should generally only be used in exceptional cases (see where the name comes from?). They are especially bad in tight loops because the execution overhead is high. Having invalid user input seems like a rather common occurrence, so I would look for another way. Take a look at this answer.
But this all depends on the language. In Python for example, try/catch is the de-facto way of coding (duck-typing).
First thank you for reading. Also I'm very aware of how I can get this to work they way I want it to. I'm just experimenting and not getting expected results.
When I run this code I would expect that when I enter the letter X I would be asked
to try again and re-attempt to enter the letter B. Well, I am. However The program will then break to the start: label and process based on the new value of input we got in the
default case. If on my second attempt I enter the letter B, nothing gets executed in the
switch statement. If you enter the letter B on your second try, the program will print that you entered B and then the program will terminate. Why is this?
import java.util.Scanner;
public class Help
{
public static void main(String[] args)
{
Scanner kb = new Scanner(System.in);
System.out.println("Enter the letter B: ");
char input = kb.nextLine().charAt(0);
start:
switch(input)
{
case 'B':
System.out.println("Nice Work!");
break;
default:
System.out.println("Try again: ");
input = kb.nextLine().charAt(0);
System.out.println(input);
break start;
}
}
}
The labeled break statement is meant for terminating loops or the switch statement that are labeled with the corresponding label. It does not transfer control back to the label. Your switch statement is simply falling through to the end of program, as it should.
A labeled break would only be helpful if you had nested switch statements and needed to break out of the outer one from the inner one.
See this for further information.
Use while cycle:
import java.util.Scanner;
public class Help
{
public static void main(String[] args)
{
Scanner kb = new Scanner(System.in);
System.out.println("Enter the letter B: ");
while(true)
{
char input = kb.nextLine().charAt(0);
switch(input)
{
case 'B':
System.out.println("Nice Work!");
break;
default:
System.out.println("Try again: ");
}
}
}
}
I'm making a school assignment and this time around I thought about using a switch statement since it looked more efficient.
It's just something basic but if I enter a letter for example and after that number 1 for example it would return case 1 twice?
This is my code for the entire class so far:
import java.util.InputMismatchException;
import java.util.Scanner;
public class Test {
private int option;
public static void main(String[] args) {
Test t = new Test();
t.start();
t.optionMenu();
}
public void start() {
System.out.println("Make your choice:");
System.out.println("1: Play");
System.out.println("2: Options");
System.out.println("3: Exit");
}
public void optionMenu() {
try {
Scanner sc = new Scanner(System.in);
this.option = sc.nextInt();
System.out.println(this.option);
} catch (InputMismatchException e) {
System.out.println("Please enter a number");
optionMenu();
}
switch (this.option) {
case 1:
System.out.println("Game starting...");
break;
case 2:
System.out.println("Loading options");
break;
case 3:
System.out.println("Game exiting...");
System.exit(0);
break;
default:
System.out.println("Enter a valid number (1, 2 or 3");
break;
}
}
}
Any help would be much appreciated, thanks!
When you call sc.nextInt() without first asking if (sc.hasNextInt()), you are open to some strange behavior when end-users start typing unexpected input, such as letters. In this case the scanner would not advance its reading pointer, so your program will get stuck reading the same incorrect output.
To fix this issue, add a loop that "clears out" the invalid entry before attempting to read an int again, like this:
while (!sc.hasNextInt()) {
System.out.print("You need to enter an integer.");
sc.nextLine(); // Clear out the bad input
}
int val = sc.nextInt(); // At this point we know that sc.hasNextInt(), because that's the loop condition
Another point is that it is not a good idea to do with recursion what can be done with iteration: the recursive call to optionsMenu is going to accumulate as many levels of invocation as the number of times the end-user enters an incorrect value, so a very persistent user could theoretically force a stack overflow on your program by entering invalid data repeatedly.
Using the code fragment above would free you from the need to call optionsMenu recursively, and also from catching the input exception.
It's just something basic but if I enter a letter for example and after that number 1 for example it would return case 1 twice?
I'm not sure what you mean here. Firstly, your idea works, this code should be fine!
Second, if you enter anything besides just the number 1, 2, or 3, you will go to the "default:" block of code. Since you are prompting the user again if they fail, typing "a" or "a1" into the prompt just shows the menu again. The user needs to just type "1", "2", or "3" to successfully select a menu option.