Как принять пользовательский ввод в сценарии jshell?
Вопрос:
Как принять пользовательский ввод в сценарии jshell? или что я делаю не так?
Примечание: я НЕ смотрю, как передавать аргументы в скрипт jshell.
Пример:
Например скрипт 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
Это работает, если я набираю построчно в jshell, но затем я запускаю jshell hello.java
это не так. Броски java.util.NoSuchElementException
,
Выходной я получаю:
@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
Моя система: Linux Mint 18.2 (x64), JShell Version 9.0.1
2 ответа
Вы можете решить эту проблему, но не напрямую с помощью кода на основе JShell.
Есть этот проект jshell_script_executor
: https://github.com/kotari4u/jshell_script_executor
Вы можете скачать его и с небольшими изменениями внутри JShellScriptExecutor.java
от
try(JShell jshell = JShell.create()){
в
// 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()){
и (также) небольшая модификация вашего кода (я знаю, что это не совсем то, что вы ищете - мы здесь не используем сканер):
/* 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));
Вы можете запустить его:
> 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
Ну... на самом деле это будет работать и с вашим кодом - немного измененным:
/* 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));
и попробовать
> java -cp src/main/java com.sai.jshell.extension.JShellScriptExecutor ./file_scanner.java
Enter number n1: 1
Enter number n2: 2
n1 + n2 = 3
По умолчанию jshell
делегирует выполнение удаленной виртуальной машине. Если вы пройдете--execution local
он использует тот же процесс виртуальной машины, который предоставляет экземпляр System.in
как и ожидалось. С учетом вашего вопроса следующий вызов должен помочь:
jshell --execution local hello.java
Смотрите подробности через jshell --help-extra
или просмотрите документацию по API по адресу https://docs.oracle.com/en/java/javase/11/docs/api/jdk.jshell/module-summary.html
Из JDK11 вы можете напрямую выполнить исходный файл Java:
$java Script.java