NoSuchElementException when trying to call kb.nextInt() - java

Quick question. Still fairly new to Java and my test class is giving me this error.
Please enter length of tail: Exception in thread "main" java.util.NoSuchElementException
at java.util.Scanner.throwFor(Unknown Source)
at java.util.Scanner.next(Unknown Source)
at java.util.Scanner.nextInt(Unknown Source)
at java.util.Scanner.nextInt(Unknown Source)
at LeftArrow.drawHere(LeftArrow.java:18)
at ArrowTest.main(ArrowTest.java:75)
Here is the code for the test class
public class ArrowTest
{
public static void main(String args[])
{
RightArrow right = new RightArrow();
LeftArrow left = new LeftArrow();
System.out.println("RightArrow Class: Calling drawHere()");
right.drawHere();
System.out.println("LeftArrow Class: Calling drawHere()");
left.drawHere(); //Error pointing to this line
// (at ArrowTest.main(ArrowTest.java:75))
}
}
And here is the code for the RightArrow and LeftArrow classes, just the relevant code. I commented the lines that the error was referring to.
public class RightArrow extends ShapeBase
{
public void drawHere()
{
int lengthTail, widthHead;
Scanner kb = new Scanner(System.in);
System.out.print("Please enter length of tail: ");
lengthTail = kb.nextInt();
System.out.print("Please enter an odd numbered width of arrowhead: ");
widthHead = kb.nextInt();
}
public class LeftArrow extends ShapeBase
{
public void drawHere()
{
int lengthTail, widthHead;
Scanner kb = new Scanner(System.in);
System.out.print("Please enter length of tail: ");
lengthTail = kb.nextInt(); //Error pointing to this line at LeftArrow.drawHere(LeftArrow.java:18)
System.out.print("Please enter an odd numbered width of arrowhead: ");
widthHead = kb.nextInt();
}
I commented out the right.drawHere() in the test class and it seemed to work okay. So I am fairly convinced it is because I am calling the same method from two classes derived from the same abstract class. Is there a way that I can fix this? Thanks for your help!
EDIT: I found that if I don't close the kb from the first arrow class called upon it does not throw this error. I can only assume its because of me closing System.in which is why it's causing a problem. Can anyone explain to me why making another instance of Scanner(System.in) doesn't just re-"open" System.in?

Before calling the nextInt method, you can use the hasNextInt() method on the scanner object to check if there is a value to get, which can be used to avoid exception. Try this:
if (kb.hasNextInt()){
lengthTail = kb.nextInt();
}
In your case, I think you are not providing enough inputs, which could lead to NoSuchInputException.
Have a look at the Scanner class doc for more information.

The problem is with Scanner object where while you calling right.drawHere() there you initialized the Scanner kb with System.in this will buffer through all data available in System.in left it empty for future use therefore it is throwing NoSuchElementException in left.drawHere().
Solution:
Make Scanner object kb as static and accessible for both LeftArrow and RightArrow

Related

`Enter Activity Number: Exception in thread "main" java.util.NoSuchElementException

Newbie here, The program works, I can call the class but I don't know what is this. I tried to search but it's not the same problem I encounter
import java.util.*;
public class mid_term {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
boolean ok = true;
Act1 act_1 = new Act1();
do {
System.out.println("Midterm Project...Press [0] to exit.\n\n\n");
System.out.println("[1] Activity 1 (Grade Calculator).");
System.out.print("Enter Activity Number: ");
int choice = input.nextInt();
switch (choice) {
case 1:
act_1.main(args);
break;
default:
break;
}
} while (ok);
}
}
import java.util.*;
public class Act1 {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.print("Enter Prelim Grade: ");
double prelim = input.nextDouble();
System.out.print("Enter Midterm Grade: ");
double midterm = input.nextDouble();
System.out.print("Enter Final Grade: ");
double finals = input.nextDouble();
double result = ((prelim*.30) +(midterm*.30)+ (finals*.40));
System.out.println("Final Ratings: " + result);
input.close();
}
}
Enter Activity Number: Exception in thread "main" java.util.NoSuchElementException
How can I solve this?
Enter Activity Number: Exception in thread "main" java.util.NoSuchElementException
at java.base/java.util.Scanner.throwFor(Scanner.java:937)
at java.base/java.util.Scanner.next(Scanner.java:1594)
at java.base/java.util.Scanner.nextInt(Scanner.java:2258)
at java.base/java.util.Scanner.nextInt(Scanner.java:2212)
at mid_term.main(mid_term.java:23)
In the class Act1 you call
input.close();
it closes your System.in stream in the end of the 1st iteration.
In the class mid_term you have an infinite loop, if you want your program work without NoSuchElementException, you should keep your stream open. Delete the
input.close();
I have noticed a couple of problems with your code, first of all you should not make another "main" method in your Act1 class. The main method is the first method that is invoked when you run your code, usually you only want to make one of them. There is also no reason to make it static because you created an Act1 object. Static methods are used when you dont need an object to invoke them.
The reason for why it gives you an error is because you are making two different scanners scanning System.in at the same time, I think. To fix this simply pass your scanner from the "mid_term" class to the method in Act1 (which you have hopefully renamed at this point). Also make sure not to close it at the end because otherwise it will just crash once the while loop in mid_term repeats itself.
You also might want to consider renaming "mid_term", in java it is common practise to spell the first letter of your class capitally and use camel case instead of underscores

Parsing Ints to Strings from Scanner in Try Catch

I've been given a task that I have to create a Shopping List program. I've done this in Python, and it was relatively straight forward. However, in Java I've hit a bit of a roadblock.
These are my variables, I am aware of the issues with using statics in this way and that it would be best to avoid doing it.
private static Scanner input = new Scanner(System.in);
private static String list_add = "string"; //"string" is just a place holder
private static ArrayList listFull = new ArrayList();
private static ArrayList listPos = new ArrayList();
private static int userIn = 1; //1 is also being used as place holder
Which I use in:
private static void userInput() {
boolean isValid = false;
while (!isValid) {
isValid = true;
try {
userIn=Integer.parseInt(input.next());
}
catch (InputMismatchException e) {
System.out.println("That's not a valid number!");
isValid = false;
}
}
}
The reasoning behind doing it this way is the less one needs to type the quicker the task can be completed. Which was working as nice philosophy up until I tried this. My previous attempt to solve this problem gave an infinite loop, and the second solution that came to mind returned a StackOverflowError. When I asked about avoiding the infinite loop, I was directed to another question (Endless loop while using "try and catch " block inside a "while loop") which I did not believe helpful to begin with, however found that it was (Thank you whoever marked that). I didn't get this solution to work, however, and I cannot see where I went wrong.
After trying different inputs to see if their was one specific type that killed it, these were the errors I received:
Test Case "strin":
Exception in thread "main" java.lang.NumberFormatException: For input string: "strin"
at java.lang.NumberFormatException.forInputString(Unknown Source)
at java.lang.Integer.parseInt(Unknown Source)
at java.lang.Integer.parseInt(Unknown Source)
at DebuggingMethods.AllIn(DebuggingMethods.java:17)
at DebuggingMethods.Menu(DebuggingMethods.java:33)
at DebuggingMethods.main(DebuggingMethods.java:58)
Test Case "Ten":
Exception in thread "main" java.lang.NumberFormatException: For input string: "Ten"
at java.lang.NumberFormatException.forInputString(Unknown Source)
at java.lang.Integer.parseInt(Unknown Source)
at java.lang.Integer.parseInt(Unknown Source)
at DebuggingMethods.AllIn(DebuggingMethods.java:17)
at DebuggingMethods.Menu(DebuggingMethods.java:33)
at DebuggingMethods.main(DebuggingMethods.java:58)
Test Case int(10):
Which ran with the anticipated outcome.
I had thought that I was missing a module, so I did import java.lang.*; which did not change the error. If someone has a solution, please help me out. I can't find a question that already posted that explains what I am doing wrong. When I pulled it out of the Try-Catch it was working kind of.
Full Piece
import java.util.InputMismatchException;
import java.util.*;
import java.util.Scanner;
import java.lang.*;
public class TestOne {
private static Scanner input = new Scanner(System.in);
private static String list_add = "string";
private static ArrayList listFull = new ArrayList();
private static ArrayList listPos = new ArrayList();
private static int userIn = 1;
private static void userInput() {
boolean isValid = false;
while (!isValid) {
isValid = true;
try {
userIn=Integer.parseInt(input.next());
}
catch (InputMismatchException e) {
System.out.println("That's not a valid number!");
isValid = false;
}
}
}
public static void main(String[] args) {
//titleMain();
userInput(); // For the sake of demonstration
}
}
You've got your exceptions mixed up. You're catching an InputMismatchException, which is what input.nextInt() would have thrown if the input were invalid. But you're actually using Integer.parseInt to parse the input, which throws NumberFormatException in case of invalid input. And since NumberFormatException isn't a subclass of InputMismatchException, it isn't caught and you end up dying with a stack trace.
You don't actually need to do anything with exception at all here. The Scanner can tell you if the next input is a valid integer or not and you can then actively decide what do about it. Think along these lines:
Scanner sc;
//...
System.out.println("Please enter a number");
while (!sc.hasNextInt()){
sc.nextLine(); // throw away the bad input
System.out.println("Please enter a valid number");
}
int theNum = sc.nextInt();

Java exception with scanner

I have a problem with the scanner. When I compile it, there are no problems. but when I want to run this program, I get an exception. Can any of you explain me the reason of this problem?
import java.util.Scanner;
public class CiagArytmetyczny {
public static void main(String[] args) {
Scanner s = new Scanner("System.in");
System.out.println("Podaj dlugosc ciagu: ");
int dl = s.nextInt();
int element = 2;
for(int i=1; i<=dl; i++) {
element=element+3;
System.out.println(element);
}
}
}
Podaj dlugosc ciagu:
Exception in thread "main" java.util.InputMismatchException
at java.util.Scanner.throwFor(Scanner.java:864)
at java.util.Scanner.next(Scanner.java:1485)
at java.util.Scanner.nextInt(Scanner.java:2117)
at java.util.Scanner.nextInt(Scanner.java:2076)
at CiagArytmetyczny.main(CiagArytmetyczny.java:8)
Process completed.
You have a problem in this line
Scanner s = new Scanner("System.in");
You are passing a string to the Scanner constructor. According to the java docs (Scanner(String source)), a new Scanner that produces values scanned from the specified string will be returned. According to the rest of your program, a String with a number should be provided for the scanner to pick up in the following line.
int dl = s.nextInt();
If you intend to get input from the console, Please change the scanner initialization as follows.
There are few more constructors to Scanner, I suggest you have a look at the java docs.
Scanner s = new Scanner(System.in);
This will give the console input stream to the Scanner.

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.

could not figure out the exception in this code snippet of java

i have tried this code snippet but could not able to figure out the reason for this the exception.
my code is:-
import java.util.*;
class ScannerTest
{
public static void main(String[]args)
{
String csv = "Sue,5,true,3";
Scanner sc = new Scanner(csv);
sc.useDelimiter(",");
int age = sc.nextInt();
System.out.println(age);
}
}
Output is:-
Exception in thread "main" java.util.InputMismatchException
at java.util.Scanner.throwFor(Unknown Source)
at java.util.Scanner.next(Unknown Source)
at java.util.Scanner.nextInt(Unknown Source)
at java.util.Scanner.nextInt(Unknown Source)
i am new to java so please help me out to know the reason for this exception.
in the javadoc example you can see how it works:
String input = "1 fish 2 fish red fish blue fish";
Scanner s = new Scanner(input).useDelimiter("\\s*fish\\s*");
System.out.println(s.nextInt());
System.out.println(s.nextInt());
System.out.println(s.next());
System.out.println(s.next());
s.close();
your first token is a string. if you use next int it expects an integer.
you might want to use something like this (under the conditions that you know the structure of the csv and it doesn't change):
public static void main(String[]args)
{
String csv = "Sue,5,true,3";
Scanner sc = new Scanner(csv);
sc.useDelimiter(",");
sc.next();
int age = sc.nextInt();
System.out.println(age);
}
or
public static void main(String[] args) {
String csv = "Sue,5,true,3";
String ageString = csv.split(",")[1];
System.out.println(ageString);
}
...
to parse a string into int:
int age = Integer.parseInt(ageString);
The Javadoc of the nextInt method of Scanner states
Scans the next token of the input as an int. This method will throw
InputMismatchException if the next token cannot be translated into a
valid int value as described below. If the translation is successful,
the scanner advances past the input that matched.
As your first token is a String, this is what's going on. As in most cases in CSV's you will know what will be presented, you should read them one by one, and/or use the hasNextInt method and its friends to check whether what you expect is actually there.
The scanner is expecting an integer type but the first token is a String - "Sue", To fix, place:
sc.next(); // skip "Sue"
before the call to nextInt() to consume the String token.

Categories

Resources