NoElementException in java - java

int selection;
while (true) {
selection = printing();
if (selection == 4) {
id = starting();
if (id < 1 || id > 10) {
if (id == -20150901) {
System.out.println("Exit code entered");
break;
}
id = incorrectId(id);
}
}
}
public static int printing(){
Scanner sc = new Scanner(System.in);
System.out.print("Main menu\n1: check balance\n2: withdraw\n3: deposit\n4: exit\nEnter a choice: ");
System.out.print("Enter a choice: ");
int selection = sc.nextInt();
return selection;
}
This is part of my java code.
The NoElementException occured in the third line.
If the whole code is needed, I will copy and paste here and explain what it is about.
How can I solve this exception?
I want to get keyboard input every time the loop starts.
Thank you.

Your code creates a new Scanner wrapping System.in each time you call printing(). This is incorrect. Instead, your application should create exactly one Scanner wrapping System.in, save it somewhere, and reuse it for each printing() call and all other places where you are reading from System.in.
The problem with creating multiple Scanner objects is that that the hashNext* and next* methods can cause characters to be "read ahead" characters into the Scanner's buffer. So the first printing() could "consume" all characters.
Now this may not be the actual cause of your problem. Other possible causes could be:
standard input could be empty, or
you may be (directly or indirectly) closing the System.in in some other part of the code.
However, the problem I identified is a bug that would cause application failures in other contexts ... and it is advisable to understand and fix it.

Related

Java: how to reject incorrect input and wait for proper input using Scanner

This is the basic setup for a little console-based quiz game. The answers are numbered. I want the player to give the answer number. If the input is not a number, then my program should give a warning, and wait for proper input.
Instead, what I get (after inserting something that is not a number) is an infinite loop of asking the question and presenting the answers again.
public static void main(String[] args) {
boolean quizActive = true;
while(quizActive) {
presentQuestion();
presentAnswers();
Scanner s = new Scanner(System.in);
if (s.hasNext()) {
String choice = s.next();
if (!NumberUtils.isNumber(choice)) {
presentText("Please insert the answer number.");
} else {
System.out.println("You made a choice!");
checkAnswer(choice);
quizActive = false;
}
s.close();
}
}
}
What am I doing wrong here?
If you do not want to question and answers be presented each time move presentQuestion() and presentAnswers() outside the loop.
But main problem is that you closing Scanner.
Remove s.close(); and move Scanner s = new Scanner(System.in); outside of the loop.
I really don't get the point in using scanner for acquiring user input.
The scanner class is perfect to process structured input from a flat file with known structure like an CSV.
But user input need to deal with all the human imperfection. After all the only advantage you get is not needing to call Integer.parseInt() your yourself at the cost to deal with the not cleared input when scanne.nextInt() fails...
So why not using InputStreamReader aside with a loop suggested by others?
Here an Example :
public class Application {
public static void main(String [] args) {
System.out.println("Please insert the answer number. ");
while (true) {
try {
Scanner in = new Scanner(System.in);
int choice = in.nextInt();
System.out.println("You made a choice!");
checkAnswer(choice);
break;
} catch (Exception e) {
System.out.println("Invalid Number, Please insert the answer number ");
}
}
}
}
You started your Quiz in a loop which is regulated by your quizActive boolean. That means that your methods presentQuestion() and presentAnswers() get called every time the loop starts again.
If you don't input a number but a character for example, your program will run the presentText("Please insert the answer number.") and start the loop again. As it starts the loop again, it will call the methods presentQuestion() and presentAnswers().
To stop that, you can do another loop around the input-sequence. Also your Scanner s = new Scanner(System.in) should be outside the loop. And you shouldn't close your Scanner right after the first input and then open it again!
if you want a code example, please tell me :)

Java Scanner no line found, and then Scanner closed error?

I have Java code that asks for user input and then stores this data in a string variable. The below function is part of a class called 'number' and is called in the main function.
public static void setVal(int i){
Scanner readIn = new Scanner(System.in);
//while (readIn.hasNextLine()){
str = readIn.nextLine();
numCheck = false;
if (i == 1){
while (!numCheck){
if (str.contains(" ")){
System.out.println("Please input a single item.");
str = readIn.nextLine();
}
else if (!isNumeric(str)){
System.out.println("Please input a valid number.");
str = readIn.nextLine();
}
else {
numCheck = true;
value = Double.parseDouble(str);
readIn.close();
}
}
readIn.close();
}
else if (i == 2){
while (!numCheck){
if (str.contains(" ")){
System.out.println("Please input a single item.");
str = readIn.nextLine();
}
else if (!isNumeric(str)){
System.out.println("Please input a valid number.");
str = readIn.nextLine();
}
else {
numCheck = true;
secondV = Double.parseDouble(str);
readIn.close();
}
}
readIn.close();
}
else {
System.out.println("An error has occurred.");
}
// }
readIn.close();
}
Part of the main function looks like this:
number input = new number();
for (int i = 1; i <= 2; i++){
input.setVal(i);
System.out.println("Now please input a second value for computing with the first.");
input.setVal(i);
}
I use the same function twice but handing it a different argument to distinguish assignment of the input to a different variable but when it runs a second time it throws a no line found error.
Applying some other advice you can see commented out I have added a 'hasNextLine()' check to check if the line exists before executing the code but this ends up at a 'Scanner closed' error even though I invoke a new instance of Scanner every time the function runs. I have also closed the scanner appropriately to ensure minimisation of errors.
I have no idea what's going wrong as I can create a Scanner in the main function and call '.nextLine()' as many times as requried without an error but when called again through a class method, I receive these errors.
Any help is appreciated, thanks in advance.
Scanner.close() documentation states that
If this scanner has not yet been closed then if its underlying
readable also implements the Closeable interface then the readable's
close method will be invoked. If this scanner is already closed then
invoking this method will have no effect.
On closing scanner, you are also closing System.in input stream, so when you reopen the scanner it will not find any open input stream.
Refer : java.util.NoSuchElementException - Scanner reading user input
Better pass scanner object from outside method as argument and then close it in calling method only when you are done with it.
Just to point out, is your String object str Static?
If not then you can't use it in your static method. Better you remove the static from method declaration.
You have to close the scanner when everything is done.
You have closed the scanner inout stream readIn.close(); twice.
You are closing the stream before picking line by line from the file. So you have to close it once after all the instances that use readIn is finished.

How to properly close a Scanner class inside a method?

I have this code that calls to a method in order to check if a number is a certain length, and if not, a new number should be reintroduced by the user.
Problem here is, I can't find the proper way to close a Scanner class in order to prevent a resource leak.
Here's the code so far.
public static void setIdentification(Person p, int dni) {
Scanner input = new Scanner (System.in);
String lengthChecker = Integer.toString(dni);
if (lengthChecker.length() < 1 || lengthChecker.length() > 8) {
int dni1;
do{
System.out.println("The ID number isn't valid. Please, introduce a valid number: ");
dni1 = input.nextInt();
lengthChecker = Integer.toString(dni1);
} while (lengthChecker.length() > 8 || lengthChecker.length() < 1 );
p.dni = dni1;
} else {
p.dni = dni;
}
}
public static void main(String[] args) {
Scanner input1 = new Scanner (System.in);
int dni = input1.nextInt();
Person person1 = new Person();
setIdentification(person1, dni);
}
I have tried to set the input.close(); in a number of different locations but I always end up getting a run-time error.
There's probably a million ways to optimize this code but right now I'm just really curious as to how to get those Scanners closed.
#Jules is correct. In this case, it is neither necessary or advisable to close the Scanner.
But assuming that you did, then the recommended way to do it is this:
try (Scanner input1 = new Scanner (System.in)) {
int dni = input1.nextInt();
Person person1 = new Person();
setIdentification(input1, person1, dni);
}
... noting that you must change your setIdentification method so that it doesn't attempt to open its own scanner. Creating multiple scanners for the same input stream is a mistake. Indeed, it is the mistake in your code.
This works for Java 7 and later. (Under most circumstances, you should not be writing new code for older versions of Java. Android is an exception, because support for Java 7 extensions has only recently become available in Android toolchains.
So why can't you open and close multiple scanners on the same stream? Two reasons:
When you close a Scanner, you automatically close the underlying stream. That means if you then attempt to open / use another scanner on the stream, it will fail when you attempt to read from the closed stream. Streams cannot be reopened.
Even if you don't close the scanner / stream, creating a second scanner on a stream is likely to lead to trouble. A scanner has to read ahead in order to figure out where the token boundaries are. It then keeps any read-ahead characters in an internal buffer. Each scanner has its own buffer. So if you have two or more scanners for the same stream, and interleave their use, one scanner is liable to "grab" characters that the other scanner needs.
Closing your scanner will close the input stream it was created using. In your case, this is System.in. This stream is a special case: it is opened by the environment before your program starts running, and therefore should not usually be closed by your program.
In this case, it's fine to not close your Scanner. Just let the garbage collector deal with it.

How do I ensure that Scanner hasNextInt() asks for new input?

New programmer here. This is probably a really basic question, but it's stumping me nevertheless.
What I'm trying to do is write a method that supplies only one integer input so I can use that input in my main program without having to mess around with non-integer inputs. However, even writing the method to do that in its own method seems to be problematic.
public static int goodInput () {
Scanner input = new Scanner (System.in); //construct scanner
boolean test = input.hasNextInt(); //set a sentinel value
while (test == false) { //enter a loop until I actually get an integer
System.out.println("Integers only please"); //tell user to give me an integer
test = input.hasNextInt(); //get new input, see if it's an integer
}
int finalInput = input.nextInt(); //once i have an integer, set it to a variable
input.close(); //closing scanner
return finalInput; //return my integer so I don't have to mess around with hasNextInt over there
}
This seems to be broken in multiple levels, but I'm not really sure why.
If I enter an integer value like 0 or 1 when I'm first asked for input, it should skip the loop entirely. But, instead, it enters the loop, and prints "Integers only please". Even worse, it doesn't actually ask for input while I'm in there, and just prints that line repeatedly.
I understand the latter problem is probably due to token issues, but I'm not necessarily sure how to solve them; closing and then reopening the scanner gets Eclipse to bug me over "duplicate objects", simply assigning the old input to a garbage String variable that is never used tells me that "No line was found" at runtime, and I'm not experienced enough to think of other ways to get new input.
Even once that's solved, I need to find some way to avoid entering the loop in the case of having an integer. I don't really understand why integer inputs inter the loop to begin with, so I'm not sure how this would be possible.
Please help? Sorry if this is an old question; tried looking at past questions but none of them seem to have the same problem that I have.
You were close: this works fine for me:
Scanner input = new Scanner(System.in); //construct scanner
while(!input.hasNextInt()) {
input.next(); // next input is not an int, so consume it and move on
}
int finalInput = input.nextInt();
input.close(); //closing scanner
System.out.println("finalInput: " + finalInput);
By calling input.next() in your while loop, you consume the non-integer content and try again, and again, until the next input is an int.
//while (test == false) { // Line #1
while (!test) { /* Better notation */ // Line #2
System.out.println("Integers only please"); // Line #3
test = input.hasNextInt(); // Line #4
} // Line #5
The problem is that in line #4 above, input.hasNextInt() only tests if an integer is inputted, and does not ask for a new integer. If the user inputs something other than an integer, hasNextInt() returns false and you cannot ask for nextInt(), because then an InputMismatchException is thrown, since the Scanner is still expecting an integer.
You must use next() instead of nextInt():
while (!input.hasNextInt()) {
input.next();
// That will 'consume' the result, but doesn't use it.
}
int result = input.nextInt();
input.close();
return result;

Java -- Closing Scanner and Resource Leak

I'm learning Java and working on some projects for fun. One issue that I have run in to is that when I use a Scanner object Eclipse warns me that:
Resource Leak: 'scan' is never closed.
So, I added a scan.close(); at the end of my code and that takes care of the warning.
The problem comes in because I have other classes in the same package that also use scanner objects and and Eclipse tells me to close scanner in those classes respectively. However, when I do that it seems like it closes ALL of the scanner objects and I get errors during run time.
Here is an example of what causes the error:
import java.util.Scanner;
public class test2 {
public static void main(String [] args) {
Scanner scan = new Scanner(System.in);
int test = 0;
do {
//Do stuff
test = scan.nextInt();
System.out.println(test);
scanTest scanTest = new scanTest();
scanTest.test();
} while (test != 0);
scan.close();
}
}
import java.util.Scanner;
public class scanTest {
public void test() {
Scanner scanner = new Scanner(System.in);
int blah = scanner.nextInt();
System.out.println(blah);
scanner.close();
}
}
After scanner is closed in the scanTest class and the do loop in test2 is entered again an error occurs at the line test = scan.nextInt();
I tried moving the creation of the scanner object into the do loop just to make a new object every time as well but the error still occurs.
Not sure why this is happening or how I can make sure all my I/O objects are closed out without running into problems.
One post I came across mentioned that when System.in is closed I cannot be re-opened. If this is the case would I just need to make sure a scanner object with System.in is closed at the very end of the program and #suppress all of the other scanner warnings in other classes? Or would that still leave all those scanner objects open (bad)?
First, this is no memory leak.
Second, when you close a stream wrapper, the default implementation is for it to close the stream that it wraps. This means that the first time you close your Scanner (as it is written), yes, you close System.in.
In general, one would like to avoid closing System.in if they were meaning to read from System.in again. The best way to go about this depends on your program.
One might copy the information from System.in into a buffer of some sort and then scan the buffer. One might not close the Scanner, reusing it in other locations. One might even de-reference the Scanner for garbage collection and create multiple new Scanners on System.in.
These solutions are not all equivalent, some are considered much better than others; but, it all depends on the calling program. Experiment with a few, and if you run into a problem, open a new StackOverflow question where you show the relevant portions of your code, a description of the problem, the example input, and the wrong output (along with the desired output).
Good luck.
Yes, when you close a scanner you will be closing the underlying stream (in this case System.in). To avoid this, either create a global variable of scanner which can be used by all classes or have a central point for shutting down the scanner (just before the program exits would be ideal)
Don't name all your scanners the same. If you have multiple in one thing like this:
import java.util.Random;
import java.util.Scanner;
public class DayThree {
public static void main(String[] args) {
**Scanner textScanner = new Scanner(System.in);**
// boolean operands
// String(or objects) .equals() "this".equals("that") false
// primitive data types == 'a'=='a' -> true 5==6 false
// != 'a'!='a' -> false 5!=6 true
// ! !(true) -> false !(false) true
// > 5 > 4 -> true 'a' > 'b' false
// < 5 < 4 -> false
// <=
// >=
// && -> and 5 < 6 && 7 > 10 -> false
// if either side of and is false the outcome is false
// || -> or 5 < 6 || 7 > 10 -> true
// if either side of or is true the outcome is true
//System.out.println(!(5 < 10) && (7>3) || (true && false || true));
/* <-- this is a multi line comment
System.out.println("What is the most amazing show on tv this week? ");
String show = textScanner.nextLine().toLowerCase(); //this is case sensitive
show = show.toLowerCase(); // changes the strng to a lowercase version
show = show.toUpperCase();
if(show.equalsIgnoreCase("game of thrones")){ // .equalsIgnoreCase( ignores caps/lower)
System.out.println("Yes it is!");
}
else{
System.out.println("You are wrong.");
System.out.println(show + " is clearly inferior to Game of Thrones.");
}
System.out.println("Who is your favorite character in " + show + ".");
String character = textScanner.nextLine().toLowerCase();
if(character.contains("dragon")){
System.out.println("CGI magic is so cool!");
}
else if(character.contains("lanister")){
System.out.println("Wrong house.");
}
else{
System.out.println(character + "is pretty cool I guess...");
}
*/
// asdf alternate multi line comment use ctrl + / on highlighted text.
// doing this a second time undoes the comment
// sdaf
// asdf
// asdf
// asdf
// 1. ask about favorite something (pet)
// 2. save that into a string all lowercase
// 3. have a series of if else (x3) and else statements about the something
//NOTE: DO NOT END CONDITIONALS WITH ; example: if(boolean); IS WRONG.
**Scanner numScanner = new Scanner(System.in);** // the variable tells you what to use it for
Random rand = new Random(); // this makes a new random object
System.out.println("Pick a number.");
int num = numScanner.nextInt();
int sNum = rand.nextInt(9) + 1; // gives me a random num between 1-10
// nextInt(bound)gives you a num from 0-bound
//adding one gives you a num from 1 - bound + 1
if(num > sNum){
System.out.println("Too high");
System.out.println("The number was " + sNum);
}
else if(num < sNum){
System.out.println("Too low");
System.out.println("The number was " + sNum);
}
else{
System.out.println("Wow are you psychic? ");
}
textScanner.close();
numScanner.close();
}//main method
}
Put the *scanner name goes here*.close(); for each one of your scanners. If they all have the same name then change the ones that do something different from and other scanner.

Categories

Resources