Correct use of java.util.scanner in a loop? - java

import java.util.Scanner;
public class MainMenu {
public MainMenu(){
int x = 1;
Scanner menuIn = new Scanner(System.in);
while ( x == 1 ){
String pick = "0";
System.out.println("--== Household Admin v1.0 ==--");
System.out.println("(A)dd Resident");
System.out.println("(R)emove Resident");
System.out.println("(L)ist Resident(s)");
System.out.println("pick = " + pick);
System.out.print("#: ");
pick = menuIn.nextLine();
System.out.println("pick = " + pick);
switch (pick) {
case "A":
case "a":
Resident.residentList.add( Resident.newResident() );
break;
case "R":
case "r":
break;
case "L":
case "l":
break;
case "Q":
case "q":
x = 0;
break;
default:
System.out.println("WRONG! Try again.");
break;
}
}
menuIn.close();
}
}
The first time through the loop everything works as expected. The second time throught the loop I am getting:
Exception in thread "main" java.util.NoSuchElementException: No line found
at java.util.Scanner.nextLine(Scanner.java:1540)
at household.MainMenu.(MainMenu.java:26)
at household.MyFirstGame.main(MyFirstGame.java:7)
I am not sure how to "reset" the scanner object as to be able to reuse it again.

You have your whole code in constructor of MainMenu in which you are closing the scanner by calling menuIn.close(); which is the root cause.
It seems you are creating new instances of MainMenu from main method inside MyFirstGame. Now if you call .close() on scanner object, it closes the underlying stream. So your first object gets created successfully. But when you try to instantiate second object of MainMenu you get this exception since System.in stream has been closed.
Ideally you should use single scanner object for reading user inputs. Instead of creating new scanner object in constructor every time, just create a single scanner object in main method and pass it as argument to the constructor. Something like below.
inside MyFirstGame.main
Scanner menuIn = new Scanner(System.in);
MainMenu mainMenu1= new MainMenu(menuIn);
MainMenu mainMenu2= new MainMenu(menuIn);
//.... and So on
//and close scanner object here once you have created all reaquired object.
menuIn .close();
In you MainMenu change constructor to
public MainMenu(Scanner menuIn ){
And Remove below lines from the constructor
//Scanner menuIn = new Scanner(System.in);
//menuIn.close();

Related

Input ignores IF statement if default in switch

I am doing a project (based on a tutorial). I have a switch statement and for each case, there's a default in case the user input is invalid, and I write on the console "Sorry, I do not understand your request". However, if the user instead of writing whatever, writes "exit", the program should end without that "I don't understand request" sentence showing up.
This is stated in my IF statement in the beginning. What my current project does at the moment when I type "exit" is showing that line and then stopping. I don't understand how the program completely ignores that IF statement in the beginning.
public class MainGame {
public static GameSave gameSave = new GameSave();
public static String user = "";
public static Scanner scanner = new Scanner(System.in);
public static String question;
public static int relationshipPoints;
public static void main(String[] args) {
Random random = new Random();
question = gameSave.loadGame();
// relationshipPoints = gameSave.loadPoints();
RelationshipPoints points = new RelationshipPoints();
System.out.println("\n\t*** TEXT_GAME: FIRSTDATE ***\n");
System.out.println("-You can exit the game at any time by typing 'exit'.-\n\n");
while (true) {
if (user.equalsIgnoreCase("exit")) {
System.exit(1);
break;
} else {
switch (question) {
[...]
case "2":
switch (user = scanner.next()) {
case "1":
System.out.println("\n\nThe guy you met last night was nice. You want to "
+ "get back into contact with him. Why don't you check your phone for a number?");
question = "2A";
gameSave.saveGame("2A");
break;
case "2":
System.out.println("\n\n");
question = "0";
break;
default:
System.out.println("\nI do not understand your request.\n");
question = "2";
break;
}
break;
case "2A": [...]
Try replacing your while(true) {...} with while ((user = scanner.next() != null) { ... }
It looks like you are trying to access the "user" data without first setting it.
user = scanner.nextLine(); insert this line just after entering in while loop. your problem occurs as you are checking user equal to exit but user has nothing so control goes to else portion.

No such element exception when returning to main menu

I am trying to make a currency conversion program which uses methods in one class. I have successfully managed to call my enterValues method from the mainMenu but when this method has finished, I need it to go back to the main menu. I receive the following NoSuchElement exception when calling my mainMenu method:
Exception in thread "main" java.util.NoSuchElementException: No line found
at java.util.Scanner.nextLine(Unknown Source)
at Conversion.mainMenu(Conversion.java:25)
at Conversion.mainMenu(Conversion.java:34)
at Conversion.main(Conversion.java:63)
Here is my code:
import java.util.Scanner;
public class Conversion {
int value;
public void mainMenu() {
int menuChoice;
Scanner menuScan = new Scanner(System.in);
System.out.println("1. Enter values and type -1 to stop");
System.out.println("2. Euros");
System.out.println("3. Dollars");
System.out.println("4. Yen");
System.out.println("5. Rupees");
System.out.println("6. Exit");
while (!menuScan.hasNextInt() || (menuChoice = menuScan.nextInt()) > 6) {
menuScan.nextLine();
System.err.println("Please enter a valid menu option 1 - 6: ");
}
switch (menuChoice) {
case 1:
enterValues();
mainMenu();
case 2:
}
}
public void enterValues() {
Scanner valueScan = new Scanner(System.in);
System.out.print("Enter value to convert: ");
value = valueScan.nextInt();
System.out.println("Value entered. Returning to main menu.");
valueScan.close();
}
public static void main(String[] args) {
Conversion conv = new Conversion();
conv.mainMenu();
}
}
Several issues at risk with your code:
You're creating more than one Scanner off of System.in and then closing one of them before you're done with the other Scanners, risking closing System.in.
You're mixing nextInt() with nextLine() calls on the Scanner without first handling the end of line token properly
You're using recursion where you don't want to use it -- having a method call itself.
Suggestions:
Use one and only one Scanner based on System.in and don't close it until your done.
Pass it into other methods that need it.
Every time you call nextInt() on it, call nextLine() too immediately after to handle the end of line token.
Don't use recursion here -- there are better and safer ways to re-call the main menu.
It has to do with you making more then 1 objects of your System.in. You should try to use only one if needed, and also use the correct method for the element youre trying to read (integers in your case). Also i would design the class a little different, a do while loop would be more appropriate, you also dont call break in your switch, causing it to also execute case 2 no matter wat. Here is some sample code for you to work with:
public class Main {
private int value;
private int menuChoice;
private Scanner menuScan;
private boolean stop = false; // program stops when stop == true
public static void main(String[] args){
Main main = new Main();
main.runProgram();
}
public void printMenu() {
System.out.println("Enter values and type -1 to stop");
System.out.println("1. Euros");
System.out.println("2. Dollars");
System.out.println("3. Yen");
System.out.println("4. Rupees");
System.out.println("5. Exit");
}
public void runProgram() {
stop = false;
menuScan = new Scanner(System.in);
do {
printMenu();
menuChoice = menuScan.nextInt();
switch(menuChoice){
case 1:
enterValues("Euro"); // enter the values and give it a string with the type of value that is being entered, so you can check for this later
break;
case 2:
enterValues("Dollar");
break;
case 3:
enterValues("Yen");
break;
case 4:
enterValues("Rupees");
break;
case 5:
System.out.println("Stopping program");
stop = true;
break;
default:
System.out.println("Please enter a valid number");
break;
}
}while(!stop);
}
public void enterValues(String valueType) {
System.out.print("Enter value to convert: ");
value = menuScan.nextInt();
System.out.println("Value entered. - run your conversion now. (Returning to main menu for now)");
/////// run your conversion here or create a method for this and call it now.
}
}
note i only used 1 class scoped System.in and no recursion for the main menu, its all in the loop.

While loop not cancelling out

I've ran into a weird issue.
I'm trying to make this code loop constantly until the user enters 4; when the user enters 4, I want to make it so that 'Quit_Detect' is set to false.
For some reason, it doesn't let me do that. The code still continuously loops until it is stopped manually.
Below is all of the code that I have used for this program along with some comments.
import java.util.Scanner; // Imports the scanner utility.
public class Start {
public static void main(String[] args) {
Scanner Reader = new Scanner(System.in); // Creates a new scanner.
#SuppressWarnings("unused")
boolean Quit_Detect;
Quit_Detect = true;
while (Quit_Detect = true)
{
int input; // States that input will have a datatype of 'int', or integer. Or, a whole number.
System.out.println("Please input your option.");
System.out.println("1. Door with a crack in it");
System.out.println("2. Normal Wooden Door");
System.out.println("3. Turn around");
System.out.println("4. Quit");
input = Reader.nextInt(); // Has the user define what the variable 'input' will be set to.
switch (input) // Uses the Variable 'input' to detect what case to follow.
{
case 1:System.out.println("First Option");
break;
case 2:System.out.println("Second Option");
break;
case 3:System.out.println("Third Option");
break;
case 4:Quit_Detect = false;
break;
default:System.out.println("Invalid option."); //Prints this if the user inputs any number other than 1, 2, or 3.
}
}
}
}
You should use:
while (Quit_Detect)
instead of:
while (Quit_Detect = true)
The first statement checks if Quit_Detect is true where the second sets the value of Quit_Detect to true.

java using NetBeans IDE 8.0.2

I am having trouble clearing the following error '(' or '[' expected on the second line of case 2 and case 3. The code I have written is newAnimal.displayInfo();
I am not sure why I get this error on case 2 and 3 but not case 1. Not sure what I am doing wrong. Any assistance/guidance will be appreciated.
Here is what the code looks like:
package animalinfo;
import java.util.Scanner;
public class AnimalInfo
{
/**
* #param args the command line arguments
*/
public static void main(String[] args)
{
// TODO code application logic here
Scanner input = new Scanner (System.in);
Animal newAnimal;
int quit = 4;
while(-4 != quit);
{
System.out.println("\n1) Camel" +
"\n2)Penguin" +
"\n3) Tortoise" +
"\n4) Exit Program.");
System.out.print("Please select an amimalfrom the list.");
int choice = input.nextInt();
switch (choice)
{
case 1:
newAnimal = new Camel();
newAnimal.displayInfo();
break;
case 2:
newAnimal = new Penguin
newAnimal.displayInfo();
break;
case 3:
newAnimal = new Tortoise
newAnimal.displayInfo();
break;
case 4:
System.out.println ("Thank you for making your selections.");
break;
}
}
}
}
It seems like you're missing parentheses after creating the new objects. So this:
newAnimal = new Penguin
should become this:
newAnimal = new Penguin();
This is because you're setting newAnimal to a new instance of a Penguin object, and to create that new instance you must call the constructor of the Penguin class to create the object.
Also, as Jurko stated, your while loop is set up incorrectly.
while(-4 != quit);
You must remove the semicolon, otherwise the loop will indefinitely run without executing the code you have underneath it. The correct syntax for a while loop is
while (-4 != quit) {
// Code to repeat here
}
while(-4 != quit);
Get rid of the semicolon, should just be
while (-4 != quit)
{
/*Code here*/
}
and yes, when you have new Penguin and new Tortoise, you are missing the parentheses and semicolon

Issue with multiple uses of Scanner.nextLine();

So, I have some code which, when simplified, is this:
import java.util.scanner
private Scanner input;
int enterInteger()
{
System.out.println("Enter the quantity");
return input.nextInt();
}
String enterString()
{
return input.nextLine();
}
void main()
{
System.out.println("Enter option: 1) Add Quantity\n2)Edit Item");
String input = enterString();
switch (input)
{
case "1":
enterInteger();
break;
case "2":
//Do whatever
break;
default:
System.out.println("Invalid!");
main();
break;
}
}
So, whenever the user enters the option as 1, it loads enterInteger() that asked the user, and returns, an integer.
However, when this happens, and the user enters the integer and presses enter, the code then begins executing the default: case. When I add a breakpoint the value of option is "", so that's obviously why the default: executes, but I can't see how to prevent it.
I know it's something dumb, so thank you.
I don't know the reason yet, But in the past I had to work with only nextLine() and parse with Integer.parseInt() when necessary.
By the way, You haven't initialized the Scanner.
Scanner input = new Scanner(System.in);

Categories