I tried to test 2 ways of getting data from user. I faced 2 errors, as I attached.
First error:
Second error:
I have second error (Obeject is never closed) with every object which I create from Scanner class!
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Scanner;
public class InputStreamReaderClass {
public static void main(String[] args) {
// Method 1:
InputStreamReader reader = new InputStreamReader(System.in);
BufferedReader buffer = new BufferedReader(reader);
System.out.println("Type text 1: ");
String text = buffer.readLine();
//Method 2:
Scanner scanner = new Scanner (System.in);
System.out.println("Type text 2: ");
String text2 = scanner.nextLine();
}
}
Method 1 you have to fix. You have to handle the error. The issue with the second method is a warning, and the program will still run without the fix, but it is a good idea to get in the habit of closing objects you're not using.
Method 1 needs to be surrounded by a try/catch statement, or you need to throw and exception:
try{
// Method 1:
InputStreamReader reader = new InputStreamReader(System.in);
BufferedReader buffer = new BufferedReader(reader);
System.out.println("Type text 1: ");
String line = buffer.readLine();
}catch(Exception e){
//handle error
}
This is because BufferedReader.readLine() throws an exception, and you need to handle it. You can get more info from the Java documentation
Method 2, you need to close the scanner object:
//Method 2:
Scanner scanner = new Scanner (System.in);
String line2 = scanner.nextLine();
System.out.println("Type text 2: ");
scanner.close();
You don't necessarily have to close the scanner, but it is a good practice.
Related
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)'
This question already has answers here:
System.console() returns null
(13 answers)
Closed 7 years ago.
I want to input a name and to print the first char ....
public class Test {
public static void main(String[] args) {
Console console = System.console();
System.out.println("Type your name : ");
String inputChar = console.readLine();
char firstChar = inputChar.charAt(0);
System.out.println(firstChar);
}
}
Some IDEs will return NPE for Console class. you can use the Scanner class and do it easily:
try this:
Scanner scan = new Scanner(System.in);
System.out.println("Enter a Name:");
String s = scan.next();
System.out.println(s.charAt(0));
this will print the first letter of your input String.
Using the Console class can a bit unreliable at times.
For reading console input, it would be preferrable to use either the Scanner class or a BufferedReader.
You can use a Scanner like :
Scanner scanner = new Scanner(System.in); // System.in is the console's inputstream
System.out.print("Enter text : ");
String input = scanner.nextLine();
// ^^ This reads the entire line. Use this if you expect spaces in your input
// Otherwise, you can use scanner.next() if you only want to read the next token
System.out.println(input);
You can also use BufferedReader like :
pre Java 7 syntax
try {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
System.out.print("Enter text : ");
String input = br.readLine();
System.out.println(input);
br.close();
} catch (Exception e) {
e.printStackTrace();
}
Java 7 syntax
try (BufferedReader br = new BufferedReader(new InputStreamReader(System.in))) {
System.out.print("Enter text : ");
String input = br.readLine();
System.out.println(input);
} catch (Exception e) {
e.printStackTrace();
}
Note: You need to use a try-catch statement when calling br.readLine() because it throws an IOException.
You can use Scanner if you want to read tokens (chunks of text separated by spaces). Use a BufferedReader if you want to simply read from the InputStream.
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();
}
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.
I would like to know about other ways of getting input from users using other classes like BufferedReader,etc rather than using Scanner class. So, was there any other way of getting input from the user? If so, was it efficient than Scanner class?
if you are using the Java SE6 or higher then you can make use of Console clas
Console console = System.console();
if (console==null){
System.out.print("console not available ");
}else {
String line = console.readLine("Enter name :");
System.out.print("your name :"+line);
}
You can do it simply by the following steps:
Use the BufferedReader Class and wrap it with the InputStreamReader Class.
BufferedReader br = new BufferedReader(new InputStreamReader(System.in))
//string str = br.readLine(); //for string input
int i = Integer.parseInt(br.readLine()); // for Integer Input
Now since the readLine method throws an IOException you need to catch it. The whole code will look like this:
try {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in))
//string str = br.readLine(); //for string input
int i = Integer.parseInt(br.readLine()); // for Integer Input
} catch(IOException ioe) {
ioe.PrintStackTrace();
}
You can use System.in directly, like this:
BufferedReader r = new BufferedReader(new InputStreamReader(System.in));
String line;
while ((line = r.readLine()) != null) {
System.out.println(line);
}
Although this may be a little faster than using the Scanner, it's not an apples-to-apples comparison: Scanner provides more methods for tokenizing the input, while BufferedReader can split your input into lines, without tokenizing it.
Use this:
BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in));
to create a reader for System.in, and you can use stdin.readLine() or something to get what you want.
Using a BufferedReader is MUCH more efficient than using a Scanner.
Here for example...
InputStreamReader inStream = new InputStreamReader(System.in);
BufferedReader stdin = new BufferedReader(inStream);
int num , num2;
String str[]=new String[2];
System.out.print("Please Enter Your First Number:");
str[0] = stdin.readLine();
System.out.print("Please Enter Your Second Number:");
str[1] = stdin.readLine();
num = Integer.parseInt(str[0]);
num2 = Integer.parseInt(str[1]);
A user can input data at the time of execution of the program without using a scanner class, and this can be done by using the following program.
class Demo
{
public static void main(String ar[])
{
int ab = Integer.parseInt(ar[0]);
int ba = Integer.parseInt(ar[1]);
int res = ab+ba;
System.out.print(res);
}
}
This is a basic program where a user can input data at the time of execution and get the desired result. You can add, subtract, Multiply, divide and concatenate strings, in CMD and a user can input data after compiling the java program i.e at the time of calling the class file. You just need to call the class file and then enter the data after a space.
C:\Users\Lenovo\Desktop>java Demo 5 2
Here ab= 5 and ba= 2. A user can have any number or string if he wants.