I am very new to Java but am working through the book Java: How to program (9th ed.) and have reached an example where for the life of me I cannot figure out what the problem is.
Here is a (slightly) augmented version of the source code example in the textbook:
import java.util.Scanner;
public class Addition {
public static void main(String[] args) {
// creates a scanner to obtain input from a command window
Scanner input = new Scanner(System.in);
int number1; // first number to add
int number2; // second number to add
int sum; // sum of 1 & 2
System.out.print("Enter First Integer: "); // prompt
number1 = input.nextInt(); // reads first number inputted by user
System.out.print("Enter Second Integer: "); // prompt 2
number2 = input.nextInt(); // reads second number from user
sum = number1 + number2; // addition takes place, then stores the total of the two numbers in sum
System.out.printf( "Sum is %d\n", sum ); // displays the sum on screen
} // end method main
} // end class Addition
I am getting the 'NoSuchElementException' error:
Exception in thread "main" java.util.NoSuchElementException
at java.util.Scanner.throwFor(Scanner.java:838)
at java.util.Scanner.next(Scanner.java:1461)
at java.util.Scanner.nextInt(Scanner.java:2091)
at java.util.Scanner.nextInt(Scanner.java:2050)
at Addition.main(Addition.java:16)
Enter First Integer:
I understand that this is probably due to something in the source code that is incompatible with the Scanner class from java.util, but I really can't get any further than this in terms of deducing what the problem is.
NoSuchElementException Thrown by the nextElement method of an Enumeration to indicate that there are no more elements in the enumeration.
http://docs.oracle.com/javase/7/docs/api/java/util/NoSuchElementException.html
How about this :
if(input.hasNextInt() )
number1 = input.nextInt(); // if there is another number
else
number1 = 0; // nothing added in the input
You should use hasNextInt() before assigning value to variable.
NoSuchElementException will be thrown if no more tokens are available. This is caused by invoking nextInt() without checking if there's any integer available. To prevent it from happening, you may consider using hasNextInt() to check if any more tokens are available.
I faced this Error with nextDouble(), when I input numbers such as 5.3, 23.8 ... I think that was from my PC depending on computer settings that use Arabic (23,33 instead 23.33), I fixed it with add:
Scanner scanner = new Scanner(System.in).useLocale(Locale.US);
You must add input.close() at the end...
This error is mostly occur in case of 0nline IDE's on which you are testing your code. It is not configured properly, as if you run the same code on any other IDE/Notepad it works properly because the online IDE is not designed such a way that it will adjust the input code of your format, So you have to take input as the Online IDE supports.
If I may, I solved this issue today by realizing that I had multiple functions that used an instance of a Scanner, each. So basically, try refactoring so that you have only one instance opened and then closed in the end - this should work.
For anyone using gradle's application plugin, you must wire it to the standard console in build.gradle(.kts) otherwise it will keep throwing the NoSuchElementException error if you try to use scanner.
For groovy:
run {
standardInput = System.in}
For gradle kotlin dsl:
tasks.withType<JavaExec>() {
standardInput = System.`in`}
Integer#nextInt throws NoSuchElementException - if input is exhausted
You should check if there is a next line with Integer#hasNextLine
if(sc.hasNextLine()){
number1=sc.nextInt();
}
I added a single static scanner (sc) at the top of my class and closed it (sc.close()) when coming out of the whole class wherever I used return statements. Again that's one instance of scanner as suggested by another answer, which should be static.
package com.example.com;
import java.util.Scanner;
public class someClass {
static Scanner sc = new Scanner(System.in);
//Whole world of methods using same sc.
//sc.close()); return;
}
Other than that you can add #SuppressWarnings("resource") on the top of the troubling method to make the warning go away. But be careful about resource leaks.
Related
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.
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;
I'm struggling with the following code which supposed to compare numbers fractions and output some text to user informing him whether the fractions of numbers are the same, i.e.
User inputs two doubles: 3.14 and 4.14
Output: Fractions are the same
User input two double: 3.14 and 4.15
Output: Franctions are not the same
Somehow I've managed to compile the following code but once I tried to run it in Eclipse IDE I came accross the following notifications:
Exception in thread "main" java.util.InputMismatchException
at java.util.Scanner.throwFor(Scanner.java:909)
at java.util.Scanner.next(Scanner.java:1530)
at java.util.Scanner.nextDouble(Scanner.java:2456)
at comparison.main(comparison.java:12)
import java.util.Scanner;
class comparison
{
public static void main(String[] args)
{
Scanner scan = new Scanner(System.in);
double a,b;
a = scan.nextDouble();
b = scan.nextDouble();
compare(a,b);
}
public static void compare(double n, double m)
{
if(n- Math.floor(n) == m - Math.floor(m))
System.out.println("Fractions are the same");
else
System.out.println("Fractions are no the same");
}
}
I would love to obtain any proper explanation of my problems, I guess there are variety of different ways to solve this case in different way but can you please stick with my idea and help me out with this ?
Thanks in advance!
try
Double.toString (n).split ("\\.")[1].equals(Double.toString (m).split ("\\.")[1])
but to fix your problem change to
a = scan.nextDouble();
scan.nextLine (); // consume CR
b = scan.nextDouble();
The documentation for InputMismatchException states:
Thrown by a Scanner to indicate that the token retrieved does not
match the pattern for the expected type, or that the token is out of
range for the expected type.
So, basically, your scanner is trying to get a double, and you apparently entered something that either was not a double or was out of the range of a double.
The best way to handle this would probably be to get Strings from the scanner, and then check to see if they can be converted to doubles. Output an error message if not.
Edit - in agreement with #scary-wombat - use BigDecimal - it has a constructor that takes a String. Be sure to catch NumberFormatException, which will be thrown if what you enter cannot be converted.
I made a program that asks for 3 integers to output type of triangle. Everything runs and compiled successfully, however, it seems the part where it asks the user to see if they want to loop it again, the online compiler outputs the error:
Exception in thread "main" java.util.NoSuchElementException
at java.util.Scanner.throwFor(Scanner.java:838)
at java.util.Scanner.next(Scanner.java:1347)
at Assignment5.main(Assignment5.java:56)
import java.util.Scanner;
public class Assignment5 {
public static void main (String[]args)
{
for (int a = 0; a < Integer.MAX_VALUE; a++)
{
Scanner userInput = new Scanner(System.in);
Scanner answer = new Scanner(System.in);
int x,y,z;
System.out.println("Enter the sides of the triangle: ");
x = userInput.nextInt();
y = userInput.nextInt();
z = userInput.nextInt();
Tri isos = new Tri(x,y,z);
Tri equal = new Tri(x,y,z);
Tri scalene = new Tri(x,y,z);
// check the equilateral triangle
System.out.println(equal.toString() + " triangle:");
if (equal.is_isosceles())
System.out.println("\tIt is isosceles");
else
System.out.println("\tIt is not isosceles");
if (equal.is_equilateral())
System.out.println("\tIt is equilateral");
else
System.out.println("\tIt is not a equilateral");
if (equal.is_scalene())
System.out.println("\tIt is scalene");
else
System.out.println("\tIt is not scalene");
System.out.println("Would you like to enter values again? (y/n)" );
String input = answer.next(); //Exception is thrown from here
if (input.equals("y"))
{
System.out.println("ok");
}
else if(!input.equals("y"))
{
System.out.println("Ok, bye.");
break;
}
}
}
}
NoSuchElementException:
Thrown by the nextElement method of an Enumeration to indicate that
there are no more elements in the enumeration.
You're getting this exception because Scanner#next doesn't read the new line character, which is the character when you press enter (\n), so in the next for iteration, you're trying to read it, which causes the exception.
One possible solution is to add answer.nextLine() right after answer.next() in order to swallow this extra \n.
Example of your code:
Iteration (a) | input for scanner | Data for scanner
--------------+-----------------------+-------------------
0 | "Hello" (And enter) | Hello
1 | \n | PROBLEM!
to me it seems that answer.next() does not actually have any value assigned to it
usually int name = answer.next() name is assigned what ever answer is. What i mean is that name cant be assigned a value because answer.next() doesn't have one.
At least this is my understanding. The alternative is the get rid of answer.next and use the other scanner.
actually an edit to this.
a scanner reads from files or the console. You have one scanner already (userInput) the second scanner isn't actually doing anything as well as it being an actual scanner, it doesn't have anything to read.
get rid of answer as a scanner, replace is with an int, String, double and have
int answer = userInput.nextInt();
or
double answer = userInput.nextDouble();
or
String answer = userInput.nextLine();
As you said the code runs for you but doesn't when compiled and executed on an online compiler. The answer scanner is exhausted because it doesn't have any elements.
It's embarrassing but i once got the same error when compiling my code on an online compiler, it turned out i wasn't supplying input beforehand to the input section and was expecting the online compiler to ask for the input.
Since you are using two scanners to get input from console, try using the scanner userInput to take the input from a file instead. (It may vary for different online compilers, but there will be an option to provide input from file)
This is my first program in java and I haven't found any good websites like this one for C++ and it's confusing for me because I just started writing java and I just came from C++. Anyways, concerning this code, could someone explain how to fix this code because of the line containing Scanner and/or how to simply receive inputs, because I haven't found any simple way to translate cin >> from C++
public class input {
public static void main(String[] args) {
double total = 0;
Scanner in = new Scanner(System.in);
System.out.println("As you enter numbers, they will be added.");
System.out.println("Entering a non-number will stop the program.");
while (in.hasNextDouble()) {
double n = in.nextDouble();
total = total + n;
System.out.println("The total is " + total);
}
}
}
Your code works. Just make sure you have import java.util.Scanner. On a related note, use Eclipse or Netbeans as they would have told you this. Also, you should capitalize class names and put your class in a package instead of in the "default package". I recommend "Head First Java".
package sand1;
import java.util.Scanner;
public class Input {
public static void main(String[] args) {
double total = 0;
Scanner in = new Scanner(System.in);
System.out.println("As you enter numbers, they will be added.");
System.out.println("Entering a non-number will stop the program.");
while (in.hasNextDouble()) {
double n = in.nextDouble();
total = total + n;
System.out.println("The total is " + total);
}
}
}
Here is output when I ran it. I think I might consider it a bug that I was able to hit enter with a blank line without it ending.
run:
As you enter numbers, they will be added.
Entering a non-number will stop the program.
12.2
The total is 12.2
43
The total is 55.2
a
BUILD SUCCESSFUL (total time: 11 seconds)
I'm at work and don't have the jdk installed, so I can't compile and run this. Giving a quick look though, it seems like the only thing you might have problem breaking out of the scanner, though. After entering a few numbers, try pressing ctrl-d - this should signal end of input.
As Borealid said you need to add the following line at the top of the class to get it to compile:
import java.util.Scanner;
Also note that by convention in java classes are named with an uppercase character Input, not input.
Finally, you can obtain input directly through System.in.read() and the other overloaded permutations of the read() method, against System.in
Check out the Java Tutorials,they're quite good for a beginner