Using try(Scanner scan = new Scanner(System.in)) { } is causing
Exception in thread "main" java.util.NoSuchElementException
When I try to debug it says that
Variable information not available, source compiled without -g option.
and shows the below code
public Scanner(InputStream source) {
this(new InputStreamReader(source), WHITESPACE_PATTERN);
}
One of my methods that uses this line:
protected String loginName(){
String username;
String password;
try (Scanner scan = new Scanner(System.in)) { // This line is causing the error.
System.out.print("Enter Username: ");
username = scan.next();
System.out.print("Enter Password: ");
password = scan.next();
}
if(getUsernamesList().contains(username))
if(password.equals(getPasswordsList().get(getUsernamesList().indexOf(username)))) return username;
else return "-1";
else return "-1";
}
You're closing System.in (a global-variable). Please, do not do that. Everywhere you have
try(Scanner scan = new Scanner(System.in))
guarantees that System.in will be close(d). Once it's close(d) you can't read from it again (or you get your mentioned Exception). Also, you can compile with debug symbols (or step into it with your IDE's built-in debugger or jdb as applicable). The Scanner.close() Javadoc says (in part),
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
Have you tried not using the try?
String username;
String password;
Scanner scan = new Scanner(System.in);
System.out.print("Enter Username: ");
Related
Even though the file Movie_db.txt isn't empty, I get the following exception:
the text file consists of this:
hank horror 20.0 18 1
public void syncDB(List<Movie> movieList) throws IOException {
Scanner scanner = new Scanner("Movie_db.txt");
BufferedReader reader = null;
try {
String line = null;
String title;
String genre;
double movieDuration;
int ageRestriction;
int id;
while (scanner.hasNext()) {
title = scanner.next();
genre = scanner.next();
movieDuration = scanner.nextDouble();
ageRestriction = scanner.nextInt();
id = scanner.nextInt();
movieList.add(new Movie(title, genre, movieDuration, ageRestriction, id));
}
} catch (Exception e) {
System.out.println("List is empty");
}
}
Considering your path is correct, there is a problem in your code. I'd change this line
Scanner scan = new Scanner("Movie_db.txt");
with this one
Scanner scan = new Scanner(Paths.get("Movie_db.txt"));
The reason is that in your snippet the Scanner only reads the string "Movie_db.txt" and in the second snippet it recognizes as the path to file.
Read Scanner documentation for more info
genre = scan.next(); line is throwing exception because nothing is left to read from file now, which causes catch block to execute.
You are providing a string to Scanner which is a valid input for scanner. Hence, it never reads the file.
Scanner scan = new Scanner(new File("full_path_to_container_dir/Movie_db.txt"));
Please have a look at this blog on how to read from a file using scanner - https://www.java67.com/2012/11/how-to-read-file-in-java-using-scanner-example.html.
I have two versions of Java code that gets user input until user types "q"
Version 1:
public class Test {
public static void main(String[] args) {
String input = "";
while (!input.equals("q")) {
Scanner scanner = new Scanner(System.in);
System.out.print("Input: ");
input = scanner.nextLine();
System.out.println("Input was: " + input);
}
}
}
Version 2:
public class Test {
public static void main(String[] args) {
String input = "";
while (!input.equals("q")) {
try(Scanner scanner = new Scanner(System.in)){
System.out.print("Input: ");
input = scanner.nextLine();
System.out.println("Input was: " + input);
}
}
}
}
Version 1 works as expected but version 2 does not work as expected.
That is after reading user input for the first time, it produces an error
Input: 12
Input was: 12Exception in thread "main"
Input: java.util.NoSuchElementException: No line found
at java.util.Scanner.nextLine(Scanner.java:1540)
at RealEstateCompany.main(RealEstateCompany.java:115)
My guess is since version 2 uses try with resource so it closes the scanner after being used and that is causing an error?
Thank you for your help in advance!
[Update]
Version 3:
public class Test {
public static void main(String[] args) {
String input = "";
try(Scanner scanner = new Scanner(System.in)){
while (!input.equals("q")) {
System.out.print("Input: ");
input = scanner.nextLine();
System.out.println("Input was: " + input);
}
}
}
}
Version 3 works. However, why version 3 is ok and version 2 is not ok?
Adding a little bit more detail to my comments
A try-with block is defined as follows:
try(...) {
...
}
where the argument in parenthesis needs to be an instance of java.lang.AutoCloseable. An example is the class java.io.InputStream, which is also the class for System.in.
A try-with attempts to automatically close its provided resource, once the block is left. Depending on the used resource, it closes all its own child resources as well.
Taking your example, you have try(Scanner scanner = new Scanner(System.in)), which uses Scanner as resource. The scanner itself uses System.in as resource. Once the try block is left (when } is reached) it tries to close its resources, which is the Scanner instance. This instance also tries to close its resource, the System.in.
Once System.in is closed, you can't get any input from the console anymore (at least not with some additional work, I think...).
Concretely, in your second example:
while (!input.equals("q")) {
try(Scanner scanner = new Scanner(System.in)){
...
} // <--- The block is left, scanner is closed, System.in is closed
} // <-- start a new iteration
Here after just one iteration, System.in gets closed. Sure, you create a new Scanner in the next iteration, but System.in remains closed, that's why you get your exception in this case.
Your third example:
try(Scanner scanner = new Scanner(System.in)){
while (!input.equals("q")) {
...
} // <-- start a new iteration, while still in the same try block
} // <-- only after the while, your resources are closed
Here you're looping your while, while still being inside try. So no resource gets closed, until you leave while and try. That means, the one Scanner remains intact and with it the one System.in. This allows you to keep reading from the console until you're done looping.
Try this:
String input = "";
try (Scanner scanner = new Scanner(System.in)) {
while (!input.equals("q")) {
System.out.print("Input: ");
input = scanner.nextLine();
System.out.println("Input was: " + input);
}
}
You can use every class thats implements Closeable or AutoCloseable in try-with-resources, When code reaches the end of the try call, It call close() function of the Scanner class in our example.
i run some tests and add the catch block into your code.here's the code
public static void main(String[] args) {
String input = "";
while (!input.equals("q")) {
try(Scanner scanner = new Scanner(System.in)){
System.out.print("Input: ");
input = scanner.nextLine();
System.out.println("Input was: " + input);
}
catch (Exception e) {
e.printStackTrace();
}
}
}
when add the catch block,there are 2 kinds of results
1,only inputs q, works as expected
2,inputs any other String, exception
Input: java.util.NoSuchElementException: No line found
at java.util.Scanner.nextLine(Scanner.java:1585)
at rews.pub.Test.main(Test.java:11)
when added the catch block, we will see that the program won't stop, because of the while loop
here is another easier test
public class Test {
public static void main(String[] args) {
String input = "";
Scanner scanner = new Scanner(System.in);
System.out.println("inout--1---");
input = scanner.nextLine();
scanner.close();
Scanner scanner2 = new Scanner(System.in);
System.out.println("inout--2---");
input = scanner2.nextLine();
scanner2.close();
}
}
and it goes same exception
inout--1---
11
inout--2---
Exception in thread "main" java.util.NoSuchElementException: No line found
at java.util.Scanner.nextLine(Scanner.java:1585)
at rews.pub.Test.main(Test.java:15)
here's my opinion.
in the end of first run, try()block will close the resource which is in the block, means we close the system.in
system.in is a object of inputSteam,and system.in is final and static, we can't open it again like 'new Scanner(System.in)'
I have declared two strings and reading the input using Scanner(System.in).
After this when i am closing the Scanner and again reading the another input using the Scanner,then it throws an error: NoSuchElementException.
Please guide me on this
import java.util.Scanner;
import java.io.*;
public class NumericInput
{
public static void main(String[] args)
{
// Declarations
Scanner in = new Scanner(System.in);
String string1;
String string2;
// Prompts
System.out.println("Enter the value of the First String .");
// Read in values
string1 = in.nextLine();
// When i am commenting below line(in.close) code is working properly.
in.close();
Scanner sc = new Scanner(System.in);
System.out.println("Now enter another value.");
string2 = sc.next();
sc.close();
System.out.println("Here is what you entered: ");
System.out.println(string1 + " and " + string2);
}
}
When you close your scanner it also closes System.in input stream, you are using it again, but it's closed, so when you try to use Scanner again, no open System.in stream is found.
There is no need to close a Scanner, since it implements AutoCloseable interface you should declare resources in try-with-resources as of java 7. If closing Scanner is an issue.
try(Scanner in = new Scanner(System.in); Scanner sc = new Scanner(System.in)){
// do stuff here without closing
}
catch(Exception){
e.printStackTrace();
}
I have the following problem: method readLine() or nextLine(), nextInt(), etc. throw an exception: NullPointerException.
I use the NetBeans IDE (if it matters).
public static void Reading()
{
String qq;
qq = System.console().readLine();
System.console().printf(qq);
}
Some IDEs don't provide a console. Note that System.console() returns null in these cases.
From the documentanion
Returns:
The system console, if any, otherwise null.
You can always use System.in and System.out instead, as follows:
String qq;
Scanner scanner = new Scanner(System.in);
qq = scanner.nextLine();
System.out.println(qq);
Two things:
The standard way of printing things is System.out.println("Thing to print");
The standard way of reading input off the console is: Scanner s = new Scanner(System.in); String input = s.nextLine();
So with these in mind, your code should be
public static void Reading() {
String qq;
Scanner s = new Scanner(System.in);
qq = s.nextLine();
System.out.println(qq);
s.close();
}
or
public static void Reading() {
String qq;
try (Scanner s = new Scanner(System.in)) {
qq = s.nextLine();
System.out.println(qq);
}
}
If trying to get user input into a string, using the code:
String X = input("\nDon't just press Enter: ");
and if they did't enter anything, to ask them until they do.
I've tried to check if it's null with while(x==null) but it doesn't work. Any ideas on what I am doing wrong/need to do differently?
input() is:
static String input (String prompt)
{
String iput = null;
System.out.print(prompt);
try
{
BufferedReader is = new BufferedReader(new InputStreamReader(System.in));
iput = is.readLine();
}
catch (IOException e)
{
System.out.println("IO Exception: " + e);
}
return iput;
//return iput.toLowerCase(); //Enable for lowercase
}
In order to ask a user for an input in Java, I would recommend using the Scanner (java.util.Scanner).
Scanner input = new Scanner(System.in);
You can then use
String userInput = input.nextLine();
to retrieve the user's input. Finally, for comparing strings you should use the string.equals() method:
public String getUserInput(){
Scanner input = new Scanner(System.in);
String userInput = input.nextLine();
if (!userInput.equals("")){
//call next method
} else {
getUserInput();
}
}
What this "getUserInput" method does is to take the user's input and check that it's not blank. If it isn't blank (the first pat of the "if"), then it will continue on to the next method. However, if it is blank (""), then it will simply call the "getUserInput()" method all over again.
There are many ways to do this, but this is probably just one of the simplest ones.