Я использую 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()
выполняются так, как я хочу, чтобы они были.
java
io
java.util.scanner
blekione
источник
источник
Ответы:
Это потому, что
Scanner.nextInt
метод не читает символ новой строки в вводе, созданном нажатием «Enter», и поэтому вызовScanner.nextLine
return возвращается после чтения этой новой строки .С подобным поведением вы столкнетесь, когда будете использовать
Scanner.nextLine
afterScanner.next()
или любой другойScanner.nextFoo
метод (кромеnextLine
самого себя).Временное решение:
Либо ставить
Scanner.nextLine
вызов после каждого,Scanner.nextInt
либоScanner.nextFoo
использовать остаток этой строки, включая перевод строкиИли, что еще лучше, прочитайте ввод
Scanner.nextLine
и преобразуйте его в нужный вам формат. Например, вы можете преобразовать в целое число, используяInteger.parseInt(String)
метод.источник
try-catch
, потому чтоInteger.parseInt
бросает,NumberFormatException
когда ему передается неверный аргумент. Вы узнаете об исключении позже. Для EG: -Integer.parseInt("abc")
. Вы не хотите, чтобы "abc" конвертировался в int, верно?Scanner#hasNextFoo
чек заранее, а не попытку, но это тоже работает.Проблема в методе input.nextInt () - он только читает значение int. Поэтому, когда вы продолжаете чтение с помощью input.nextLine (), вы получаете клавишу ввода «\ n». Поэтому, чтобы пропустить это, вы должны добавить input.nextLine () . Надеюсь, это должно быть ясно сейчас.
Попробуйте это так:
источник
nextLine
, но мне все еще нужно объяснение этого поведенияЭто потому, что когда вы вводите число, а затем нажимаете Enter,
input.nextInt()
потребляет только номер, а не «конец строки». При выполненииinput.nextLine()
он потребляет «конец строки», все еще находящийся в буфере с первого ввода.Вместо этого используйте
input.nextLine()
сразу послеinput.nextInt()
источник
Кажется, есть много вопросов по этому вопросу
java.util.Scanner
. Я думаю, что более читаемым / идиоматическим решением было бы позвонить,scanner.skip("[\r\n]+")
чтобы удалить любые символы новой строки после вызоваnextInt()
.РЕДАКТИРОВАТЬ: как @PatrickParker отметил ниже, это приведет к бесконечному циклу, если пользователь вводит любой пробел после числа. Смотрите их ответ для лучшего шаблона для использования с пропустить: https://stackoverflow.com/a/42471816/143585
источник
Это происходит потому,
input.nextInt();
что не захватывает перевод строки. Вы можете сделать как другие предложенные, добавивinput.nextLine();
внизу.В качестве альтернативы вы можете сделать это в стиле C # и проанализировать nextLine в целое число следующим образом:
Делать это работает так же хорошо, и это экономит вам строку кода.
источник
TL; DR Использовать
scanner.skip("\\R")
перед каждымscanner.newLine()
вызовом, который выполняется после:scanner.next()
scanner.next*TYPE*()
метод.Вещи, которые вам нужно знать:
текст, представляющий несколько строк, также содержит непечатаемые символы между строками (мы называем их разделителями строк), например
"\r"
)"\n"
)когда вы читаете данные из консоли, это позволяет пользователю вводить свой ответ, а когда он это делает, ему необходимо каким-то образом подтвердить этот факт. Для этого пользователю необходимо нажать клавишу «ввод» / «возврат» на клавиатуре.
Важно то, что этот ключ помимо обеспечения помещения пользовательских данных на стандартный ввод (представленный,
System.in
который читаетсяScanner
) также отправляет зависимые от ОС разделители строк (как для Windows\r\n
) после него.Поэтому, когда вы запрашиваете у пользователя значение типа
age
, а пользователь вводит 42 и нажимает ввод, стандартный ввод будет содержать"42\r\n"
.проблема
Scanner#nextInt
(и другие методы) не позволяют СканеруScanner#nextType
использовать эти разделители строк. Он будет читать их изSystem.in
(как иначе Сканер узнает, что от пользователя больше нет цифр, представляющихage
значение, а не с пробелами?), Что удалит их из стандартного ввода, но он также кеширует эти разделители строк внутри . Нам нужно помнить, что все методы Scanner всегда сканируют, начиная с кэшированного текста.Сейчас же
Scanner#nextLine()
просто собирает и возвращает все символы, пока не найдет разделители строк (или конец потока). Но поскольку разделители строк после считывания числа с консоли сразу обнаруживаются в кэше сканера, он возвращает пустую строку, то есть сканер не смог найти ни одного символа перед этими разделителями строк (или концом потока).КСТАТИ
nextLine
также потребляет эти разделители строк.Решение
Поэтому, когда вы хотите запросить номер, а затем и всю строку, избегая при этом пустую строку
nextLine
, либоnextInt
из кэша сканеровnextLine
,skip("\\R")
илиskip("\r\n|\r|\n")
позволить сканеру пропустить часть, совпадающую с разделителем строк (подробнее о\R
: https://stackoverflow.com/a/31060125 )nextInt
(ниnext
какие-либоnextTYPE
методы) вообще. Вместо этого читайте все данные построчно с помощьюnextLine
и анализируйте номера из каждой строки (при условии, что одна строка содержит только одно число) для правильного типа, например,int
черезInteger.parseInt
.КСТАТИ : методы могут пропустить разделители (по умолчанию всех непечатаемые как вкладки, разделители строк) , включая те , кэшируется сканером, пока они не найдут следующее значение без разделителей (маркер). Спасибо за ввод кода
Scanner#nextType
"42\r\n\r\n321\r\n\r\n\r\nfoobar"
сможет правильно назначить
num1=42
num2=321
name=foobar
.источник
Вместо
input.nextLine()
использованияinput.next()
это должно решить проблему.Модифицированный код:
источник
Если вы хотите прочитать как строки, так и целые числа, решение состоит в том, чтобы использовать два сканера:
источник
scanner.nextLine()
должен работать.Если вы хотите быстро сканировать ввод, не путаясь с методом класса сканера nextLine (), используйте для этого пользовательский сканер ввода.
Код:
Преимущества:
Методы:
Применение :
ScanReader sc = new ScanReader(System.in);
3. Импортируйте необходимые классы:import java.io.BufferedInputStream; import java.io.IOException; import java.io.InputStream;
4. Бросьте IOException из вашего основного метода для обработки Exception 5. Используйте предоставленные методы. 6. НаслаждайтесьПример :
источник
Чтобы избежать проблемы, используйте
nextLine();
сразу после,nextInt();
поскольку это помогает в очистке буфера. При нажатии не захватывает новую строку и , следовательно, пропускает код позже.ENTER
nextInt();
Scanner
источник
sc.nextLine()
лучше по сравнению с анализом ввода. Потому что по производительности это будет хорошо.источник
Я думаю, что я довольно поздно на вечеринку ..
Как уже говорилось, вызов
input.nextLine()
после получения значения int решит вашу проблему. Причина, по которой ваш код не работал, заключалась в том, что больше нечего было хранить из вашего ввода (куда вы ввели int)string1
. Я просто пролью немного света на всю тему.Рассмотрим nextLine () как нечетный среди методов nextFoo () в классе Scanner. Давайте рассмотрим небольшой пример. Допустим, у нас есть две строки кода, подобные приведенным ниже:
Если мы введем значение ниже (в виде одной строки ввода)
Значения наших
firstNumber
иsecondNumber
переменных становятся 54 и 234 соответственно. Причина, по которой это работает таким образом, заключается в том, что новый перевод строки ( т.е. \ n ) НЕ генерируется автоматически, когда метод nextInt () принимает значения. Это просто берет "следующий int" и движется дальше. То же самое относится и к остальным методам nextFoo (), за исключением nextLine ().nextLine () генерирует новый перевод строки сразу после получения значения; это то, что @RohitJain означает, говоря, что новый перевод строки "потребляется".
Наконец, метод next () просто берет ближайшую строку без генерации новой строки; это делает этот метод предпочтительным для получения отдельных строк в одной строке.
Я надеюсь, что это помогает .. Веселое кодирование!
источник
Используйте 2 объекта сканера вместо одного
источник
источник
если я ожидаю непустой ввод
используется в приведенном выше примере:
источник
В одном из моих вариантов использования у меня был сценарий чтения строкового значения, которому предшествовала пара целочисленных значений . Я должен был использовать цикл for / while для чтения значений. И ни одно из вышеперечисленных предложений не сработало в этом случае.
Использование
input.next()
вместоinput.nextLine()
исправленной проблемы. Надеюсь, что это может быть полезно для тех, кто имеет дело с подобным сценарием.источник
Используйте этот код, чтобы решить вашу проблему.
источник
Как
nextXXX()
методы не читаютnewline
, кромеnextLine()
. Мы можем пропуститьnewline
после прочтения любогоnon-string
значения (int
в этом случае), используяscanner.skip()
как показано ниже:источник
Почему бы не использовать новый сканер для каждого чтения? Как ниже. При таком подходе вы не столкнетесь со своей проблемой.
источник
Scanner
чтобы предотвратить утечку памяти. Трата времени?nextInt()
не будет использовать новую строку независимо от того, является ли она новойScanner
или уже использованной.