I'm making this program that lists websites, username, and password data (kind of like a passwords manager), and in the console I get this:
Select: Not a valid entry! repeats twice
I'm not sure why this is happening, but here is the code block:
System.out.print("PASSCODE: ");
passcode = (char) System.in.read();
if(passcode == '}'){
System.out.println("Welcome! Enter 'Q' to exit at any time!");
System.out.println("1) Website A \n2) Website B \n3) Website C \n4) Website D");
for(;(char) choice != 'Q';){
System.out.print("SELECT: ");
choice = (char) System.in.read();
switch(choice){
case '1':
websiteA.Display();
break;
case '2':
websiteB.Display();
break;
case '3':
websiteC.Display();
break;
case '4':
websiteD.Display();
break;
default:
System.out.println("\nNot a valid entry!");
}
}
} else {System.out.println("ACCESS DENIED");}
I'm confused, because I would think the code would halt at System.in.read() in the for loop.
Aside from the objects, everything here is a conglomeration of what I've learned up to chapter 3 from Java: A Beginner's Guide Eight Edition by Herbert Schildt. So I'm still somewhat new to this.
When you enter a char, there's actually 2 char sent, the first one is your key, the second is the line break char code, aka \n. So with the loop, it will process twice for each choice.
Related
It works fine with '1'but with the other options it runs 3x times (by printing out the whole Menu
thing before allowing user input again.
char a;
do {
System.out.println ("MENU");
System.out.println ("Press 1 to EXIT");
System.out.println ("Press 2 to PLAY");
System.out.println ("Press 3 for SETTINGS");
a = (char)System.in.read();
switch (a){
case '1':
System.out.println ("You have EXITED");
break;
case '2':
System.out.println ("GAME OVER");
break;
case '3':
System.out.println ("You chose SETTINGS");
break;
}
}while (a != '1');
By default the console (or similar) is line buffered, so you type a digit followed by return/enter. You are reading a character at a time. The three characters you see are the digit, Carriage Return (CR/'\r') and New Line (NL/'\n').
See this question How to read a single char from the console in Java (as the user types it)? Alternatively read a line at a time - most example programs will use java.util.Scanner.
You have to reset the a as '1'. The reason it was executing repeatedly is because the value of as is not reset
This question already has answers here:
How to read a single char from the console in Java (as the user types it)?
(7 answers)
Closed 3 years ago.
I'm a new programmer. I'm coding a user menu and I've a question on the do-while loop. When main() calls my first method containing my first loop it works as expected. However, when the user selects makes a choice and customerMenu() is called, it prints the menu 3 times. Why is this? Is there a mistake in my code?
public class Runner {
public static void main(String[] args) {
Menu m = new Menu ();
m.mainMenu();
}
}
public class Menu {
private char choice;
public void mainMenu () {
try {
do {
System.out.println("Create Order");
System.out.println("View Orders");
System.out.println("Customers");
System.out.println("Employees");
choice = (char) System.in.read();
} while (choice < '1' || choice > '4');
System.out.println("\n");
switch (choice) {
case '1':
System.out.println("Create Order page");
break;
case '2':
System.out.println("View Orders page");
break;
case '3':
customerMenu();
//System.out.println("Customers page");
break;
case '4':
System.out.println("Employees page");
break;
}
} catch (Exception e) {
System.out.println("Error");
}
}
// Do loop prints 3 times
public void customerMenu () {
try {
do {
System.out.println("Add a Customer");
System.out.println("Edit a Customer");
System.out.println("Delete a Customer");
choice = (char) System.in.read();
} while (choice < '1' || choice > '3');
System.out.println("\n");
switch (choice) {
case '1':
System.out.println("Add a Customer action");
break;
case '2':
System.out.println("Edit a Customer action");
break;
case '3':
System.out.println("Delete a Customer action");
break;
}
} catch (Exception e) {
System.out.println("Error");
}
}
}
There are no problems with the logic of your program but instead of using System.in.read () use either Scanner or BufferedReader. I can only guess that the three other characters that System.in.read () read are the null byte, line feed, and carriage return.
I just tried out the code (link to test env) and for me the menu is printing two times, not three.
The reason it prints twice is because System.in.read() reads in the next byte of data. When you type '3' and hit enter, that sends two bytes of data to the input stream. One byte for the 3 and one byte to indicate 'newline'.
The first time the do-while loop is entered, it reads in the 'newline' byte. That causes the loop to run a second time. The second time around, there's no more bytes to read so it waits for input for user.
Hi there i found your're mistake, i am not good with java. hmm maybe just printing the choice variable you will find your answer.
in mainmenu you have the choice variable and when you called customerMenu on the do while loop the choice variable is read again.
solution create another variable for customerMenu.
I am trying to make a program where the user has to answer a multiple choice question. The program works completely fine when the user enters A, B, C, or D. But if they enter "Z" for example, it stops working at a certain point. The program will proceed as prompted by saying "Invalid answer, please enter A, B, C, or D." But when you select A, B, C, or D, the program suddenly ends instead of showing whether or not the user was correct.
I tried to call the getAnswer() method again as the default case in the switch statement, so the program will ask the user for their choice again. Before I added this line, it didn't do that at all. However, it's still not following through with that last step. Here's the code:
// Call the method that will ask the user the question.
askQuestion();
// Call the method that will allow the user to answer.
getAnswer();
switch(userChoice)
{
case 'a':
case 'A':
System.out.println("Incorrect! 'Switch' IS a key word. The correct answer was B. ");
System.out.println("The program will now end. Thanks for answering!");
System.exit(0);
break;
case 'b':
case 'B':
System.out.println("Correct!");
System.out.println("The program will now end. Thanks for answering!");
System.exit(0);
break;
case 'c':
case 'C':
System.out.println("Incorrect! 'Float' IS a key word. The correct answer was B. ");
System.out.println("The program will now end. Thanks for answering!");
System.exit(0);
break;
case 'd':
case 'D':
System.out.println("Incorrect! 'True' IS a key word. The correct answer was B. ");
System.out.println("The program will now end. Thanks for answering!");
System.exit(0);
break;
default:
System.out.println("Invalid character.");
// Repeats the getAnswer method to retrieve a valid character.
getAnswer();
}
}
// method that will ask the question
public static void askQuestion()
{
// Show the user the possible answers for the multiple choice questions.
System.out.println("Which of these is NOT a Java key word?");
System.out.println("A: switch");
System.out.println("B: keyboard");
System.out.println("C: float");
System.out.println("D: true");
}
// method that will retrieve the answer from the user
public static char getAnswer()
{
// create another Scanner object
Scanner keyboard = new Scanner(System.in);
// Tell the user to select their answer and store it in a variable.
System.out.println("Select your answer by pressing A, B, C, or D.");
String input = keyboard.nextLine();
userChoice = input.charAt(0);
// Return the user's answer to main.
return userChoice;
}
Ideally, if the user presses Z, but then presses A the next time around, it will tell the user is wrong, but the program is just ending instead of providing feedback. What am I missing?
It's best to use a loop here. You keep looping until the user enters a valid response:
askQuestion();
while (true) {
userChoice = getAnswer();
switch(userChoice)
{
case 'a':
case 'A':
System.out.println("Incorrect! 'Switch' IS a key word. The correct answer was B. ");
System.out.println("The program will now end. Thanks for answering!");
System.exit(0);
...
default:
System.out.println("Invalid character.");
}
}
Note that you don't need the break statements after each System.exit(0) call.
You could move the askQuestion() call inside the while loop if you wanted to re-ask the question on a bad input.
you can use a recurring method call when an invalid answer is received
public void doProcess(){ //this will keep getting called until a valid key is read.
askQuestion();
userChoice = getAnswer();
switch(userChoice)
{
case 'a':
case 'A':
case 'b':
//program will exit/ correct wrong ans etc etc
break;
default:
//call itself again
doProcess();
}
}
Your switch case only checks for a single time only for the first answer.
You can have function for finidng the answer itself.
import java.util.Scanner;
public class Main
{
// method that will ask the question
public static void askQuestion()
{
// Show the user the possible answers for the multiple choice questions.
System.out.println("Which of these is NOT a Java key word?");
System.out.println("A: switch");
System.out.println("B: keyboard");
System.out.println("C: float");
System.out.println("D: true");
}
// method that will retrieve the answer from the user
public static char getAnswer()
{
// create another Scanner object
Scanner keyboard = new Scanner(System.in);
// Tell the user to select their answer and store it in a variable.
System.out.println("Select your answer by pressing A, B, C, or D.");
String input = keyboard.nextLine();
char userChoice = input.charAt(0);
// Return the user's answer to main.
return userChoice;
}
public static void main(String[] args) {// Call the method that will ask the user the question.
askQuestion();
// Call the method that will allow the user to answer.
char userChoice = getAnswer();
while(!checkForCorrectAnswer(userChoice)){
userChoice = getAnswer();
}
}
private static boolean checkForCorrectAnswer(char userChoice){
switch(userChoice)
{
case 'a':
case 'A':
System.out.println("Incorrect! 'Switch' IS a key word. The correct answer was B. ");
System.out.println("The program will now end. Thanks for answering!");
System.exit(0);
return true;
case 'b':
case 'B':
System.out.println("Correct!");
System.out.println("The program will now end. Thanks for answering!");
System.exit(0);
return true;
case 'c':
case 'C':
System.out.println("Incorrect! 'Float' IS a key word. The correct answer was B. ");
System.out.println("The program will now end. Thanks for answering!");
System.exit(0);
return true;
case 'd':
case 'D':
System.out.println("Incorrect! 'True' IS a key word. The correct answer was B. ");
System.out.println("The program will now end. Thanks for answering!");
System.exit(0);
return true;
default:
System.out.println("Invalid character.");
// Repeats the getAnswer method to retrieve a valid character.
return false;
}
}
}
To avoid having to use the case expression to verify if it is lowercase or uppercase, I recommend that you use the following:
String value = String.valueOf(userChoice).toUpperCase();
This helps to make the conversion of lowercase to uppercase before doing the evaluation in the switch case.
So I'm currently dealing with this [keep in mind I cut most of the code out cause it's quite long]
int choice = 0;
while (choice != 7){
System.out.println("--- Mathematical Calculator ---");
System.out.println("");
System.out.println("Pick an operation from the list - Use nos. 1 to 7");
System.out.println("1) Multiplication");
System.out.println("2) Division");
System.out.println("3) Addition");
System.out.println("4) Subtraction");
System.out.println("5) Find the area of a regular object");
System.out.println("6) Find the volume of a regular object");
System.out.println("7) Exit Program");
**boolean ok = false;
do {
try{
choice = userInput.nextInt();
ok = true;
} catch (InputMismatchException e){
System.out.println("Invalid input");
}
}
while (ok = false);**
switch (choice) {
case 1:
case 2:
case 3:
case 4:
case 5:
case 6:
case 7:
System.out.println("Thanks for using my program");
System.out.println("Program terminated");
break;
default: System.out.println("Invalid choice");
}
}
userInput.close();
}
So currently, when I run the program and enter something that is NOT an integer, the program will give the following output:
--- Mathematical Calculator ---
Pick an operation from the list - Use nos. 1 to 7
1) Multiplication
2) Division
3) Addition
4) Subtraction
5) Find the area of a regular object
6) Find the volume of a regular object
7) Exit Program
Invalid input
Invalid choice
Over
And over
And over
I know I've probably done something wrong with the exception handling (program works fine with valid input), but I really don't know how I can fix it.
Help?
You need to catch the \n\r with an userInput.nextLine() in your exception and it stops printing for ever like this
catch (InputMismatchException e){
System.out.println("Invalid input");
userInput.nextLine();
}
while (ok = false); should be while (ok == false);, or while (!ok);.
ok = false is an assignment.
Also, I guess you have intentionally left the cases empty, but even so, make sure that you put a break; on each of them, otherwise the option 7 will always be executed.
EDIT: for the infinite loop, you should also do what Kevin Esche suggests in his answer (+1).
So I'm guessing that the solution to this is going to be really simple but I have no idea what I'm looking for so I'd like some help. What happens is that when I run the program, and choose case 1. It prints both "dog's name" and "dogs race" without giving me a chance to fill in the dogs name. So when I choose case 1 I start out only getting to fill in dogs race, how heavy, and how old it is! here is the code I'm using...
do {
System.out.println("(1 - reg\n2 - tail\n3- delete\n4-exit\nEnter number: ");
// so this is where the switch stuff starts
int option=sc.nextInt();
switch (option) {
case 1: System.out.println("Dog's Name: ");
String na=sc.nextLine();
System.out.println("Dog Race: ");
String ra=sc.nextLine();
System.out.println("How heavy?");
double wey=sc.nextDouble();
System.out.println("How old?");
double ag=sc.nextDouble();
dog doggy= new dog(na, ra, wey, ag);
kennel.add(doggy);
break;
case 2: System.out.println("its a tail");
break;
case 3: System.out.println("you delete");
break;
case 4: System.out.println("QUITTING\n(Data was not saved srry.)");
play = false;
default: System.out.println("try again");
}
}while(play);
I believe you need to call nextLine() after your call to nextInt(), because that hasn't advanced the scanner to the next line yet.
There's a newline reminder from your first sc.nextInt, you can change the delimiter to \n or just call nextLine(); just after reading the option (Using sc.useDelimiter("\n") )
Try:
int option=Integer.parseInt(sc.nextLine());
This has both the effect of advancing the cursor to the next line and getting the typed number.