Сканер пропускает nextLine () после использования next () или nextFoo ()?
я использую Scanner
методы nextInt()
и nextLine()
для чтения входных данных.
это выглядит так:
System.out.println("Enter numerical value");
int option;
option = input.nextInt(); // Read numerical value from input
System.out.println("Enter 1st string");
String string1 = input.nextLine(); // Read 1st string (this is skipped)
System.out.println("Enter 2nd string");
String string2 = input.nextLine(); // Read 2nd string (this appears right after reading numerical value)
проблема в том, что после ввода числового значения, первый input.nextLine()
пропускается, а второй input.nextLine()
выполняется, так что мой вывод выглядит следующим образом:
Enter numerical value
3 // This is my input
Enter 1st string // The program is supposed to stop here and wait for my input, but is skipped
Enter 2nd string // ...and this line is executed and waits for my input
я протестировал свое приложение, и похоже, что проблема заключается в использовании input.nextInt()
. Если я удалю его, то оба string1 = input.nextLine()
и string2 = input.nextLine()
выполняются так, как я хочу, чтобы они быть.
15 ответов:
вот так
Scanner.nextInt
метод не потребляет последние строки характер вашего ввода, и при этом что новая строка потребляется при следующем вызовеScanner.nextLine
.вы столкнетесь с подобным поведением при использовании
Scanner.nextLine
послеScanner.next()
иScanner.nextFoo
способ (кромеnextLine
сам.)решение:
либо стрелять холостым
Scanner.nextLine
звонить послеScanner.nextInt
илиScanner.nextFoo
потреблять остальную часть этой строки, включая новая строкаint option = input.nextInt(); input.nextLine(); // Consume newline left-over String str1 = input.nextLine();
или, было бы еще лучше, если бы вы прочитали ввод через
Scanner.nextLine
и конвертировать входные данные в нужный вам формат. Например, к целому числу с помощьюInteger.parseInt(String)
метод.int option = 0; try { option = Integer.parseInt(input.nextLine()); } catch (NumberFormatException e) { e.printStackTrace(); } String str1 = input.nextLine();
проблема с вход.nextInt() метод-он только считывает значение int. Поэтому, когда вы продолжаете читать с вводом.nextLine () вы получаете ключ ввода "\n". Так, чтобы пропустить это, вы должны добавить вход.nextLine (). Надеюсь, теперь это должно быть ясно.
попробуйте вот так:
System.out.print("Insert a number: "); int number = input.nextInt(); input.nextLine(); // This line you have to add (It consumes the \n character) System.out.print("Text1: "); String text1 = input.nextLine(); System.out.print("Text2: "); String text2 = input.nextLine();
это потому, что когда вы вводите номер, затем нажмите введите,
input.nextInt()
потребляет только число, а не "конец строки". Когдаinput.nextLine()
выполняется, он потребляет "конец строки" все еще в буфере от первого входа.вместо этого используйте
input.nextLine()
сразу послеinput.nextInt()
там, кажется, много вопросов об этой проблеме с
java.util.Scanner
. Я думаю, что более читаемым / идиоматическим решением было бы позвонитьscanner.skip("[\r\n]+")
чтобы удалить любые символы новой строки после вызоваnextInt()
.EDIT: как @PatrickParker отметил ниже, это вызовет бесконечный цикл, если пользователь вводит любые пробелы после числа. Смотрите их ответ для лучшего шаблона для использования с skip:https://stackoverflow.com/a/42471816/143585
Он делает это, потому что
input.nextInt();
не захватывает новую строку. вы могли бы сделать, как и другие предложенные, добавивinput.nextLine();
внизу.
В качестве альтернативы вы можете сделать это в стиле C# и разобрать следующую строку на целое число, например:int number = Integer.parseInt(input.nextLine());
это работает так же хорошо, и это экономит вам строку кода.
вещей, которые вы должны знать:
текст, который представляет несколько строк, также содержит непечатаемые символы между строками (мы называем их разделителями строк), например
- возврат каретки (CR-в строковых литералах, представленных как
"\r"
)- подача строки (LF-в строковых литералах, представленных как
"\n"
)когда вы читаете данные с консоли, это позволяет пользователю ввести его ответ и когда он закончит он должен как-то подтвердить этот факт. Для этого пользователю необходимо нажать клавишу "enter"/"return" на клавиатуре.
важно то, что этот ключ помимо обеспечения размещения пользовательских данных стандартный ввод (в лице
System.in
, который считываетсяScanner
) также отправляет зависимые от ОС разделители строк (например, для Windows\r\n
) после него.поэтому, когда вы просите пользователя для значения, как
age
, и пользователь вводит 42 и нажимает enter, стандартный ввод будет содержать"42\r\n"
.
вместо
input.nextLine()
использоватьinput.next()
, это должно решить проблему.измененный код:
public static Scanner input = new Scanner(System.in); public static void main(String[] args) { System.out.print("Insert a number: "); int number = input.nextInt(); System.out.print("Text1: "); String text1 = input.next(); System.out.print("Text2: "); String text2 = input.next(); }
чтобы избежать этой проблемы, используйте
nextLine();
сразу послеnextInt();
как это помогает в очистке буфера. При нажатии кнопкиENTER
thenextInt();
не захватывает новую строку и, следовательно, пропускаетScanner
код позже.Scanner scanner = new Scanner(System.in); int option = scanner.nextInt(); scanner.nextLine(); //clearing the buffer
если вы хотите быстро сканировать ввод, не путаясь в методе класса сканера nextLine (), используйте для этого пользовательский сканер ввода .
код :
class ScanReader { /** * @author Nikunj Khokhar */ private byte[] buf = new byte[4 * 1024]; private int index; private BufferedInputStream in; private int total; public ScanReader(InputStream inputStream) { in = new BufferedInputStream(inputStream); } private int scan() throws IOException { if (index >= total) { index = 0; total = in.read(buf); if (total <= 0) return -1; } return buf[index++]; } public char scanChar(){ int c=scan(); while (isWhiteSpace(c))c=scan(); return (char)c; } public int scanInt() throws IOException { int integer = 0; int n = scan(); while (isWhiteSpace(n)) n = scan(); int neg = 1; if (n == '-') { neg = -1; n = scan(); } while (!isWhiteSpace(n)) { if (n >= '0' && n <= '9') { integer *= 10; integer += n - '0'; n = scan(); } } return neg * integer; } public String scanString() throws IOException { int c = scan(); while (isWhiteSpace(c)) c = scan(); StringBuilder res = new StringBuilder(); do { res.appendCodePoint(c); c = scan(); } while (!isWhiteSpace(c)); return res.toString(); } private boolean isWhiteSpace(int n) { if (n == ' ' || n == '\n' || n == '\r' || n == '\t' || n == -1) return true; else return false; } public long scanLong() throws IOException { long integer = 0; int n = scan(); while (isWhiteSpace(n)) n = scan(); int neg = 1; if (n == '-') { neg = -1; n = scan(); } while (!isWhiteSpace(n)) { if (n >= '0' && n <= '9') { integer *= 10; integer += n - '0'; n = scan(); } } return neg * integer; } public void scanLong(long[] A) throws IOException { for (int i = 0; i < A.length; i++) A[i] = scanLong(); } public void scanInt(int[] A) throws IOException { for (int i = 0; i < A.length; i++) A[i] = scanInt(); } public double scanDouble() throws IOException { int c = scan(); while (isWhiteSpace(c)) c = scan(); int sgn = 1; if (c == '-') { sgn = -1; c = scan(); } double res = 0; while (!isWhiteSpace(c) && c != '.') { if (c == 'e' || c == 'E') { return res * Math.pow(10, scanInt()); } res *= 10; res += c - '0'; c = scan(); } if (c == '.') { c = scan(); double m = 1; while (!isWhiteSpace(c)) { if (c == 'e' || c == 'E') { return res * Math.pow(10, scanInt()); } m /= 10; res += (c - '0') * m; c = scan(); } } return res * sgn; } }
плюсы :
- сканирование ввода быстрее, чем BufferReader
- Уменьшает Сложность Времени
- сбрасывает буфер для каждого следующего входа
методы :
- scanChar () - сканирование одного символа
- scanInt() - сканировать целочисленное значение
- scanLong () - сканировать длинное значение
- scanString () - сканировать строковое значение
- scanDouble () - сканировать двойное значение
- scanInt (int [] array) - сканирует полный массив(целое число)
- scanLong (long[] array) - сканирование всего массива (Long)
использование :
- скопируйте данный код ниже вашего кода java.
- инициализировать объект для данного Класс
ScanReader sc = new ScanReader(System.in);
3. Импорт необходимых классов:
import java.io.BufferedInputStream; import java.io.IOException; import java.io.InputStream;
4. Бросьте IOException из вашего основного метода для обработки исключения 5. Используйте Предоставленные Методы. 6. Наслаждайтесьпример :
import java.io.BufferedInputStream; import java.io.IOException; import java.io.InputStream; class Main{ public static void main(String... as) throws IOException{ ScanReader sc = new ScanReader(System.in); int a=sc.scanInt(); System.out.println(a); } } class ScanReader....
Если вы хотите читать обе строки и ints, решение заключается в использовании двух сканеров:
Scanner stringScanner = new Scanner(System.in); Scanner intScanner = new Scanner(System.in); intScanner.nextInt(); String s = stringScanner.nextLine(); // unaffected by previous nextInt() System.out.println(s); intScanner.close(); stringScanner.close();
sc.nextLine()
лучше по сравнению с разбора входных данных. Потому что производительность мудрый это будет хорошо.
public static void main(String[] args) { Scanner scan = new Scanner(System.in); int i = scan.nextInt(); scan.nextLine(); double d = scan.nextDouble(); scan.nextLine(); String s = scan.nextLine(); System.out.println("String: " + s); System.out.println("Double: " + d); System.out.println("Int: " + i); }
мое тестирование показало те же результаты, что и Prine, однако я подумал о довольно простом обходном пути:
используя
BufferedReader#nextLine()
, Если быScanner#readLine()
, избегает этой ошибки. Вы даже можете написать свою собственную оболочку сканера, чтобы переопределить функцию чтения строки сканера с помощью функции BufferedReader nextLine.
Я думаю, что я довольно поздно на вечеринку..
как уже было сказано, звоните
input.nextLine()
после получения вашего значения int решит вашу проблему. Причина, по которой ваш код не работал, заключалась в том, что больше нечего было хранить из вашего ввода (где вы ввели int) вstring1
. Я просто пролить немного света на всю эту тему.считают nextLine () как нечетный среди nextFoo() методы в классе сканера. Давайте возьмем небольшой пример.. Допустим, у нас есть две строки кода, как показано ниже:
int firstNumber = input.nextInt(); int secondNumber = input.nextInt();
если мы вводим значение ниже (в виде одной строки ввода)
54 234
ценности
firstNumber
иsecondNumber
переменная становится 54 и 234 соответственно. Причина, по которой это работает таким образом, заключается в том, что новая подача строки (т. е. \n)ЭТО НЕ автоматически генерируется при использовании метода nextInt принимает значения. Он просто берет "next int" и движется дальше. Это то же самое для остальных методов nextFoo() за исключением nextLine().nextLine () генерирует новый поток строк сразу после получения значения; это то, что @RohitJain означает, что новый поток строк "потребляется".
наконец, метод next () просто принимает ближайшую строку без генерация новой строки; это делает это предпочтительным методом для принятия отдельные строки в пределах одной строки.
Я надеюсь, что это помогает.. Веселого кодирования!