Почему 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
596   5  

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

    Ничего не найдено.