Почему hasNext () False, но Hasnextline () истинно?
вопрос
как это для объекта сканера hasNextLine() метод возвращает true, в то время как hasNext() возвращает false?
Примечание: На основе входного файла,hasNext() метод возвращает результат как ожидали;hasNextLine() не кажется, что возвращает правильный результат.
код
вот код, который я запускаю, что создает результаты ниже:
public void ScannerTest(Reader fileReaderObject){
Scanner scannerObj = new Scanner(fileReaderObject);
for(int i = 1; scannerObj.hasNext(); i++){
System.out.println(i + ": " + scannerObj.next());
System.out.println("Has next line: " + scannerObj.hasNextLine());
System.out.println("Has next: " + scannerObj.hasNext());
}
System.out.println();
scannerObj.close();
}
Входной Файл
следующий фактическое содержимое файла, который я передаю этому сканеру:
a 3 9
b 3 6
c 3 3
d 2 8
e 2 5
f 2 2
g 1 7
h 1 4
i 1 1
результат
ниже приведен конец того, что печатается в консоли, когда я запускаю свой код, и включает в себя часть, которую я не могу понять:
25: i
Has next line: true
Has next: true
26: 1
Has next line: true
Has next: true
27: 1
Has next line: true
Has next: false
5 ответов:
у вас есть одна дополнительная новая строка в конце файла.
hasNextLine()проверяет, есть ли другойlinePatternв буфере.hasNext()проверяет, есть ли в буфере анализируемый токен, разделенный разделителем сканера.поскольку разделитель сканера является пробелом, а
linePatternтакже белое пространство, возможно, там будетlinePatternв буфере но никаких разборных жетонов.как правило, самый распространенный способ справиться с этой проблемой, всегда называя
nextLine()после разбора всех маркеров (например, чисел) в каждой строке текста. Вы должны сделать это при использованииScannerпри чтении ввода пользователя тоже отSystem.in. Чтобы переместить сканер за этот разделитель пробелов, необходимо использоватьscanner.nextLine()чтобы очистить разделитель строк. Смотрите:используя сканер.nextLine ()
приложение:
LinePatternопределяется какPattern, который соответствует этому:private static final String LINE_SEPARATOR_PATTERN = "\r\n|[\n\r\u2028\u2029\u0085]"; private static final String LINE_PATTERN = ".*("+LINE_SEPARATOR_PATTERN+")|.+$";разделитель токенов по умолчанию-это
Pattern:private static Pattern WHITESPACE_PATTERN = Pattern.compile( "\p{javaWhitespace}+");
причина в том, что
hasNext()проверяет, есть ли еще какие-либо символы без пробелов.hasNextLine()проверяет, есть ли еще одна строка текста. Ваш текстовый файл, вероятно, имеет новую строку в конце, поэтому он имеет другую строку, но не более символов, которые не являются пробелами.многие текстовые редакторы автоматически добавляют новую строку в конец файла, если ее еще нет.
другими словами, ваш входной файл не является ли это (цифры строчку цифры):
1. a 3 9 2. b 3 6 3. c 3 3 4. d 2 8 5. e 2 5это на самом деле так:
1. a 3 9 2. b 3 6 3. c 3 3 4. d 2 8 5. e 2 5 6.
короткий ответ:
у вас есть пустая строка в конце файла.
причина для пустой строки
если вы возьмете свой контент и сохраните его, например, в txt-файл, некоторые редакторы добавят пустую новую строку в ваш файл.
Редакторы ведут себя так, потому что это часть POSIX стандартные:
3.206 строку
последовательность из нуля или более не символы плюс завершающий символ.
эта тема обсуждалась в этой теме.
документация сканера Java
вот документация от Java 8 Scanner class.
hasNext()возвращает true, если этот сканер имеет другой маркер на входе.
hasNextLine()возвращает true, если на входе этого сканера есть другая строка.
причина поведения кода Java
из-за вышеописанных фактов,
hasNextLine()вернутсяtrue, аhasNext()Не могу найти ничего, что он может распознать как и возвращаетfalse.дополнительную информацию см. durron597 пост.
вы потребляете значение
next(), но проситhasNext()иhasNextLine().next(), по умолчанию, возвращает все к следующемуwhitespace(). Таким образом, вы перебираете все пробелы, разделенные строками, и после каждого из них вы спрашиваете оnextLine().
i 1 1->hasNextLine()? Истинный.hasNext()? Тоже верно.
1 1->hasNextLine()? Истинный.hasNext()? Также верно (все еще пробел слева)
1->hasNextLine()? True (Строка Сеператор, наверное). haxNext? Ложь, больше никаких пробелов.
основная концепция hasNext () и hasNextLine () является
hasNextLine:- возвращает true, если на входе этого сканера есть другая строка. Этот метод может блокировать во время ожидания ввода. Сканер не проходит мимо какого-либо входа.
возвращает: true, если и только если этот сканер имеет другую строку ввода Бросает: IllegalStateException - если этот сканер закрыто
hasNext
возвращает true, если следующий полный маркер соответствует указанному шаблону.
полный маркер имеет префикс и постфиксацию по входу, который соответствует шаблону разделителя. Этот метод может блокировать во время ожидания ввода. Сканер не проходит мимо какого-либо входа.
параметры: pattern-шаблон для сканирования
возвращает: true если и только если это сканер имеет другой маркер, соответствующий указанному шаблону
Так как ваш последний вход говорит true для nextLine (), потому что вызов сканирования.nextLine (); возвращает следующий токен. Важно отметить, что сканер возвращает пробел и букву, потому что он читает с конца последнего маркера до начала следующей строки.
Comments