Confusin Error with Scanner - java

I keep getting this error and I do not know why :
Exception in thread "main" java.util.NoSuchElementException
at java.util.Scanner.throwFor(Scanner.java:907)
at java.util.Scanner.next(Scanner.java:1530)
at java.util.Scanner.nextInt(Scanner.java:2160)
at java.util.Scanner.nextInt(Scanner.java:2119)
at Daily.takingData(Daily.java:33)
at Daily.main(Daily.java:20)
this is my code:
import java.io.*;
import java.util.Scanner;
public class Daily
{
private static int size;
public static void main(String[] args) throws Exception {
System.out.println("Please enter amount of rows");
Scanner scan1 = new Scanner(System.in);
size = scan1.nextInt();
scan1.close();
System.out.println();
takingData(size);
}
public static void takingData(int rows) throws Exception {
System.out.println("Enter 1 To View Number of Markets");
System.out.println("Enter 2 To View Start and End Dates of Markets");
System.out.println("Enter 3 To View Start and End Dates of Contracts");
System.out.println("Enter 4 To View Averages of Markets");
System.out.println("Enter 0 To Quit Program");
int choice = 0;
Scanner scan2 = new Scanner(System.in);
choice = scan2.nextInt();
System.out.println("Got here");
scan2.close();
if (choice == 0)
System.exit(0);
}
}
My Out put is :
Enter 1 To View Number of Markets
Enter 2 To View Start and End Dates of Markets
Enter 3 To View Start and End Dates of Contracts
Enter 4 To View Averages of Markets
Enter 0 To Quit Program
(error here)

You are getting an error because you close your scanner right after you scan:
size = scan1.nextInt();
scan1.close();
and then try to scan again in takingData
remove the scan1.close(); that is outside of your takingData.
When you close a Scanner, the InputStream that it is scanning from is also closed, in this case your System.in is being closed.
When a Scanner is closed, it will close its input source if the source implements the Closeable interface.
Taken from Scanner javadocs

The problem is that you're closing the first instance of Scanner here
scan1.close();
which is closing the associated InputStream (System.in) - this prevents the second Scanner instance of reading from the stream.
Don't close the scanner. Also you could create a single instance of Scanner for reading all values.
From a design point of view I would move from static methods to an OO approach with the single Scanner instance created in the constructor of Daily and all methods becoming instance methods. This will help with testability of the Object.
public class Daily {
private final Scanner scanner;
public Daily() {
scanner = new Scanner(System.in);
}
public int getRows() {
System.out.println("Please enter amount of rows");
return scanner.nextInt();
}
public static void main(String[] args) throws Exception {
Daily daily = new Daily();
int rows = daily.getRows();
int mainOption = daily.getMainOption(rows);
switch (mainOption) {
case 0: // TODO: refactor to use enums
System.exit(0);
}
}
public int getMainOption(int rows) {
System.out.println("Enter 1 To View Number of Markets");
System.out.println("Enter 2 To View Start and End Dates of Markets");
System.out.println("Enter 3 To View Start and End Dates of Contracts");
System.out.println("Enter 4 To View Averages of Markets");
System.out.println("Enter 0 To Quit Program");
return scanner.nextInt();
}
}

The answer to your question is here: https://stackoverflow.com/a/13042296/1688441 for question:
java.util.NoSuchElementException - Scanner reading user input
I am quoting:
When you call, sc.close() in first method, it not only closes your
scanner but closes your System.in input stream as well. This you can
verify by printing its status at very top of the second method as :
System.out.println(System.in.available());
So now when you re-instantiate, Scanner in second method, it doesn't find any open
System.in stream and hence the exception.

Get rid of the initial int choice, and try this:
int choice = scan2.nextInt();
Shouldn't really make a difference, but it could help.

Related

Why is scanner reading no input and exiting function? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
I've created a method that asks a user for their favorite number. When I call this function more than once in my main, all method calls thereafter will jump to closing and declare Your favorite number is: 0 without asking for input. I'd like to know why a fresh scanner is reading and accepting no input.
public static void favNumber(){
Scanner scanner = new Scanner(System.in);
System.out.println("Enter you favorite number: ");
int favNumber = 0;
boolean hasNextInt = scanner.hasNextInt();
if(hasNextInt){
favNumber = scanner.nextInt();
scanner.nextLine(); //reads enter character
}
System.out.println("Your favorite number is: " + favNumber);
scanner.close();
}
Your Scanner instance wraps System.in (stdin). When you call scanner.close() at the end of your method, you're actually closing System.in in addition to your scanner. Once the input stream is closed, it can't be opened again.
The solution is, of course, to share a single instance of the Scanner. I note that you're using static methods, so I will similarly use a static instance in the following example. Note how I create the scanner, then I call favNumber(), and I only close the scanner after I finish calling favNumber(). This allows me to call favNumber() multiple times and share the same scanner instance.
private static Scanner scanner; // note that this is a class-level static variable.
public static void main(String[] args) throws Exception {
try {
scanner = new Scanner(System.in); // create the scanner
favNumber(); // call the method
} finally {
scanner.close(); // only close the scanner when we're completely done
}
}
public static void favNumber(){
System.out.println("Enter you favorite number: ");
int favNumber = 0;
boolean hasNextInt = scanner.hasNextInt();
if(hasNextInt){
favNumber = scanner.nextInt();
scanner.nextLine(); //reads enter character
}
System.out.println("Your favorite number is: " + favNumber);
}
An alternative solution would be to pass the scanner instance as a method parameter like this:
public static void main(String[] args) throws Exception {
Scanner scanner = new Scanner(System.in); // create the scanner
favNumber(scanner); // call the method, pass the scanner
scanner.close(); // only close the scanner when we're completely done
}
public static void favNumber(Scanner scanner){
System.out.println("Enter you favorite number: ");
int favNumber = 0;
boolean hasNextInt = scanner.hasNextInt();
if(hasNextInt){
favNumber = scanner.nextInt();
scanner.nextLine(); //reads enter character
}
System.out.println("Your favorite number is: " + favNumber);
}
You can read more about closing scanners wrapping System.in in this Q&A here: Close a Scanner linked to System.in

Continuous Scanner input

I'm writing sort of main practice project, where I can just continually add classes that do completely different fun things. For example, I have a CoinFlipperCmd and a poker PotOddsCmd, and the code currently works fine, but I want to be able to repeatedly enter commands without having to rerun the program. Example console currently:
FLIP 10 // coinflips 10 times and notes the outcome
You flipped 5 heads and 5 tails
After this, the code will exit, but I want to be able to keep entering commands. Like so:
FLIP 5
You flipped 4 heads and 1 tails
FLIP 6
You flipped 3 heads and 3 tails
POTODDS 0.5 1
You have pot odds of 2:1
I'm using a scanner for input
import java.util.Scanner; // Import the Scanner class
public class Main {
public static void main(String[] args) {
InputScanner();
}
private static void InputScanner() {
Scanner myObj = new Scanner(System.in); // Create a Scanner object
System.out.println("Enter command");
String command = myObj.nextLine(); // Read user input
ParseAndDirect(command);
}
private static void ParseAndDirect(String command) {
String[] commandSplit = command.split(" ", 2);
String usercommand = commandSplit[0];
if (usercommand.equals("FLIP")){
CoinFlipperCmd.CoinFlipperCmd(commandSplit[1]);
} else if (usercommand.equals("POTODDS")){
PotOddsCmd.PotOddsCmd(commandSplit[1]);
} else System.out.println("Invalid Command");
}
}
You need to put the input part inside a loop e.g.
private static void InputScanner() {
Scanner myObj = new Scanner(System.in); // Create a Scanner object
String command;
do {
System.out.print("Enter command (q to quit): ");
command = myObj.nextLine(); // Read user input
if (!command.equalsIgnoreCase("q")) {
ParseAndDirect(command);
}
} while (!command.equalsIgnoreCase("q"));
}
Another way of using the loop can be as follows:
private static void InputScanner() {
Scanner myObj = new Scanner(System.in); // Create a Scanner object
String command;
while(true)
System.out.print("Enter command (q to quit): ");
command = myObj.nextLine(); // Read user input
if (command.equalsIgnoreCase("q")) {
break;
}
ParseAndDirect(command);
}
}
On a side note (because it won't have any impact on the execution of the program), you should always follow Java naming conventions e.g the method, ParseAndDirect should be named as parseAndDirect and InputScanner should be named as inputScanner.
Apart from allowing the user to repeatedly enter commands, I think you should also allow some way to quit the program (besides having to kill it via the operating system :-) In the below code, I have arbitrarily used the word quit as the way to exit the loop. Feel free to use a different string.
Scanner myObj = new Scanner(System.in);
String command = "";
while (!"quit".equalsIgnoreCase(command)) {
System.out.println("Enter command");
if (!"quit".equalsIgnoreCase(command)) {
ParseAndDirect(command);
}
}
By the way, according to java naming conventions the method name should be parseAndDirect, i.e. it should start with a lowercase letter.

How do I make java wait for input before assigning the input to a variable to avoid java.util.NoSuchElementException

I'm studying Java classes and I'm trying to create a code where the user inputs how many objects (in this case "cube") they want to create.
In my main class I have this code written
System.out.println("Enter the amount of objects you want to create");
Scanner objNumInput = new Scanner(System.in);
int objNum = objNumInput.nextInt();
objNumInput.close();
Cube cubes[] = new Cube[objNum];
for (int i = 0; i < objNum; i++){
String cubeName = Cube.inputName();
double cubeLength = Cube.inputLength();
cubes[i] = new Cube(cubeName, cubeLength);
}
in my Cube class I have here:
public static String inputName(){
String cubeName;
Scanner input = new Scanner(System.in);
System.out.println("Enter the name: ");
cubeName = input.nextLine();
return cubeName;
}
public static double inputLength(){
double cubeLength;
Scanner input = new Scanner(System.in);
System.out.println("Enter the length: ");
cubeLength = input.nextDouble();
return cubeLength;
}
When I run it, I can input the number of "cubes" I want to create. Then, it keeps throwing an exception
Exception in thread "main" java.util.NoSuchElementException: No line found
at java.util.Scanner.nextLine(Scanner.java:1540)
at Cube.inputName(Cube.java:40)
at Main.main(Main.java:88)
what's wrong?
Do not close your Scanner, it will close System.in as well.
When a Scanner is closed, it will close its input source if the source implements the Closeable interface
As I understand (correct me if I'm wrong) the reason why you close your objNumInput is that you want to use it in two different methods.
I would suggest you to pass the Scanner as input parameter into your methods inputName and inputLength. Then you'll be able to reuse the same scanner without closing it in between.
public static String inputName(Scanner scanner){
String cubeName;
System.out.println("Enter the name: ");
cubeName = scanner.nextLine();
return cubeName;
}
public static double inputLength(Scanner scanner){
double cubeLength;
System.out.println("Enter the length: ");
cubeLength = scanner.nextDouble();
return cubeLength;
}
...
System.out.println("Enter the amount of objects you want to create");
Scanner objNumInput = new Scanner(System.in);
int objNum = objNumInput.nextInt();
//objNumInput.close(); <-- Do not close the scanner
Cube cubes[] = new Cube[objNum];
for (int i = 0; i < objNum; i++){
String cubeName = Cube.inputName(objNumInput);
double cubeLength = Cube.inputLength(objNumInput);
cubes[i] = new Cube(cubeName, cubeLength);
}
put objNumInput.close(); after for loop in your main method.The reason your program flashes by without pausing the second time because System.in is closed when you do objNumInput.close(); in the line number 3 of main method
closing a Scanner object will close the underlying stream.
-your code only works one time because System.in is getting closed. You cannot "open" System.in again. A closed stream cannot be reopened

Scanner variable cannot be resolved

In my program, the user will be asked to input 3 integers. The integers will then be read using the Scanner class and listed back to the user.
This is my code:
import java.util.Scanner;
public class Echoer
{
public static void main(String[] args)
{
/* The Data Below Will Read The Numbers Input Into The Prompt*/
Scanner input = new Scanner(System.in);
System.out.println("Please Enter Three Integers: ");
int number;
number = input.nextInt();
Scan.close();
System.out.println("Thanks. The Numbers You Entered Are: " + number);
}
}
This is the error it returns:
Exception in thread "main" java.lang.Error: Unresolved compilation problem:
Scan cannot be resolved
Why does it return this error? How can I fix this issue?
In your code, you never defined what Scan was. Use input.close() rather than Scan.close().
Scan cannot be resolved
means that you never defined Scan. This is because you said Scan.close(). You need to change it to input.close() because input is the name of the instance of the Scanner class.
As others pointed out, you have to close input instead of Scan as shown below.
import java.util.Scanner;
public class Echoer
{
public static void main(String[] args)
{
/* The Data Below Will Read The Numbers Input Into The Prompt*/
Scanner input = new Scanner(System.in);
System.out.println("Please Enter Three Integers: ");
int number;
number = input.nextInt();
input.close();
System.out.println("Thanks. The Numbers You Entered Are: "+number);
}
}

Use of Scanner class in recursive functions

I am trying to use a recursive method/function, which uses the Scanner class. Closing the scanner, causes an exception to be thrown the next time the same method is called within the recursion. A workaround to this is not to close the scanner at all, but this is not a right approach. I suspect the same scanner object is used between recursive calls, so that's why closing it creates havoc. If my assumption is correct then closing the scanner in the last method call would be a valid workaround (i.e. no actual resource leak). Is there anything I may be missing before jumping into Scanner and related implementation code?
EDIT
The answers provided were really useful and enlightening. In summary, the problem is the constant re-opening and closing of the scanner, and not recursion per se. The reason I would avoid passing the scanner object as parameter is that this example simulates a larger project, calling multiple recursive functions and I would have to pass the scanner object in all of them.
On the practical side, and from the answers provided, I think just closing the scanner in the last recursive call would work without having any resource leaks. Any related opinions would be welcome, esp. if you see something wrong with my approach.
Here is an example of my initial experiment:
package scanner;
import java.util.Scanner;
public class Main {
public static void acceptValidInput() {
System.out.print("Enter a number greater than 10: ");
Scanner sc = new Scanner(System.in);
int i = sc.nextInt();
// Adding this will make an exception to be thrown:
sc.close();
if (i <= 10) {
acceptValidInput();
}
}
public static void main(String[] args) {
acceptValidInput();
System.out.println("Your input is valid");
}
}
Once you start to consume an input stream using a Scanner, you should not try to read from it in any other way anymore. In other words, after you have constructed a Scanner to read from System.in, you need to use it for all further reading from System.in. This is because Scanner buffers input, so you have no idea how much input it has already consumed but not emitted yet.
Therefore, I recommend that you construct one Scanner, then use it for all the reading:
public class Main {
public static void acceptValidInput(Scanner sc) {
System.out.print("Enter a number greater than 10: ");
int i = sc.nextInt();
if (i <= 10) {
acceptValidInput(sc);
}
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
acceptValidInput(sc);
System.out.println("Your input is valid");
sc.close();
}
}
It works:
package scanner;
import java.util.Scanner;
public class Main {
public static void acceptValidInput(Scanner sc) {
int i = sc.nextInt();
if (i <= 10) {
System.out.print("Enter a number greater than 10: ");
acceptValidInput(sc);
}
}
public static void main(String[] args) {
System.out.print("Enter a number greater than 10: ");
Scanner sc = new Scanner(System.in);
acceptValidInput(sc);
sc.close();
System.out.println("Your input is valid");
}
}
The result is:
Enter a number greater than 10: 4
Enter a number greater than 10: 5
Enter a number greater than 10: 11
Your input is valid
Process finished with exit code 0
Closing the scanner closes also the underlying input stream. In this case it is the System.in stream - you shouldn't do this. Either do not close it or create a single scanner for all method calls.
public class abc{
public void acceptValidInput() {
System.out.print("Enter a number greater than 10: ");
Scanner sc = new Scanner(System.in);
int i = sc.nextInt();
// Adding this will make an exception to be thrown:
if (i <= 10) {
acceptValidInput();
}
}
public static void main(String[] args) {
while(true){
abc a=new abc();
a.acceptValidInput();
System.out.println("Your input is valid");
}
}}
try this.

Categories

Resources