How to take user input in jshell script? or what I'm doing wrong?
Note: I'm NOT looking how to pass arguments to jshell script.
For example script hello.java
:
Scanner in = new Scanner(System.in);
System.out.print("Enter number n1: ");
int n1 = in.nextInt();
System.out.print("Enter number n2: ");
int n2 = in.nextInt();
System.out.println("n1 + n2 = "+ (n1 +n2));
/exit
It works if I type line by line in jshell, but then I run jshell hello.java
it doesn't. Throws java.util.NoSuchElementException
.
Output I getting:
@myMint ~/Java $ jshell hello.java
Enter number n1: | java.util.NoSuchElementException thrown:
| at Scanner.throwFor (Scanner.java:858)
| at Scanner.next (Scanner.java:1497)
| at Scanner.nextInt (Scanner.java:2161)
| at Scanner.nextInt (Scanner.java:2115)
| at (#3:1)
Enter number n2: | java.util.NoSuchElementException thrown:
| at Scanner.throwFor (Scanner.java:858)
| at Scanner.next (Scanner.java:1497)
| at Scanner.nextInt (Scanner.java:2161)
| at Scanner.nextInt (Scanner.java:2115)
| at (#5:1)
n1 + n2 = 0
My system: Linux Mint 18.2(x64), JShell Version 9.0.1
The simplest way to obtain user input is by using the input() function. This function prompts the user for an input from the keyboard. Once the user has give the input and pressed Enter, the program flow continues. The input() function will always output a string.
The Scanner class is used to get user input, and it is found in the java.util package.
Per default, jshell
delegates execution to a remote VM. If you pass --execution local
it uses the same VM process, which provides an instance of System.in
as expected. Tailored to your question, the following call should do the trick:
jshell --execution local hello.java
See details via jshell --help-extra
or browse the API documentation at https://docs.oracle.com/en/java/javase/11/docs/api/jdk.jshell/module-summary.html
You can solve this issue, but not directly with JShell based code.
There is this project jshell_script_executor
: https://github.com/kotari4u/jshell_script_executor
You can download it, and with small modification inside JShellScriptExecutor.java
from
try(JShell jshell = JShell.create()){
to
// This call will map System.in in your main code
// to System.in inside JShell evaluated code
try(JShell jshell =
JShell.builder()
.in(System.in)
.out(System.out)
.err(System.err)
.build()){
and (also) small modification of your code (I know this is not exactly what you are looking for - we don't use Scanner here):
/* Put this code into file.jshell */
import java.io.*;
InputStreamReader read = new InputStreamReader(System.in);
BufferedReader in = new BufferedReader(read);
int n1;
System.out.print("Enter the number: ");
n1 = Integer.parseInt(in.readLine());
int n2;
System.out.print("Enter the number: ");
n2 = Integer.parseInt(in.readLine());
System.out.println("n1 + n2 = " + (n1 + n2));
you can get it running:
> javac src/main/java/com/sai/jshell/extension/JShellScriptExecutor.java
> java -cp src/main/java com.sai.jshell.extension.JShellScriptExecutor ./file.jshell
Enter the number: 1
Enter the number: 2
n1 + n2 = 3
Well ... in fact it will work with your code as well - slightly modified:
/* Put this code into file_scanner.java */
import java.util.Scanner;
Scanner in = new Scanner(System.in);
System.out.print("Enter number n1: ");
int n1 = in.nextInt();
System.out.print("Enter number n2: ");
int n2 = in.nextInt();
System.out.println("n1 + n2 = "+ (n1 +n2));
and give it a try
> java -cp src/main/java com.sai.jshell.extension.JShellScriptExecutor ./file_scanner.java
Enter number n1: 1
Enter number n2: 2
n1 + n2 = 3
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With