Как принять пользовательский ввод в скрипте 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 версии 9.0.1


person my-    schedule 02.01.2018    source источник
comment
Два взгляда на это. Один, если я считаю ввод в скрипт после int n1 = in.nextInt(); введенным вами вручную. Другое дело, что произойдет, если вы удалите из скриптов эти Return(enter) и запустите их как одну строку с операторами, разделенными точкой с запятой? Но, что интересно, сравнение скрипта и строки за строкой хорошо, чтобы увидеть разницу здесь и не забыть throws NoSuchElementException - if input is exhausted   -  person Naman    schedule 02.01.2018
comment
@nullpointer Я думал о первом способе. Добавление in.hasNextLine() check (tnx для его указания) избавит от исключения. Но теперь мне кажется, что мне нужна какая-то пауза (удерживать, пока пользователь не войдет)..?? Второй способ... Я студент (не носитель английского языка) и мало что дало моему мозгу, какого черта я только что прочитал. Я прочитал ваш пост несколько раз, подумал о том, что я только что прочитал, попробовал однострочный скрипт (результаты были такими же), перечитал ваш пост еще раз, подумал еще раз ... и все еще чувствую себя потерянным. Я что-то пропустил? Кстати, спасибо за ваше время.   -  person my-    schedule 02.01.2018


Ответы (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

person Sormuras    schedule 25.12.2019
comment
Это то, что мне нужно. - person SystemsInCode; 13.02.2020

Вы можете решить эту проблему, но не напрямую с помощью кода на основе JShell.

Есть этот проект jshell_script_executor: https://github.com/kotari4u/jshell_script_executor

Вы можете скачать его и с небольшой модификацией внутри JShellScriptExecutor.java

от

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()){

и (также) небольшая модификация вашего кода (я знаю, что это не совсем то, что вы ищете - мы здесь не используем сканер):

/* 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
person Oo.oO    schedule 13.02.2018

Из JDK11 вы можете напрямую выполнить исходный файл Java:

$java Script.java

См. раздел Запуск программ с одним файлом с исходным кодом.

person Imaskar    schedule 23.08.2018