Program Tip

hasNext ()가 False인데 hasNextLine ()이 True 인 이유는 무엇입니까?

programtip 2020. 12. 1. 19:40
반응형

hasNext ()가 False인데 hasNextLine ()이 True 인 이유는 무엇입니까?


질문

스캐너 객체의 경우 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

파일 끝에 하나의 추가 개행이 있습니다.

  • hasNextLine()linePattern버퍼에 다른 것이 있는지 확인합니다 .
  • hasNext() 스캐너의 구분 기호로 구분 된 버퍼에 구문 분석 가능한 토큰이 있는지 확인합니다.

스캐너의 구분 기호는 공백이고 linePattern역시 공백이기 때문에 linePattern버퍼에는 있지만 구문 분석 가능한 토큰은 없을 수 있습니다.

일반적으로 nextLine()텍스트의 각 줄에있는 모든 토큰 (예 : 숫자)을 구문 분석 한 후 항상 호출하여이 문제를 처리하는 가장 일반적인 방법 입니다. Scanner에서 사용자 입력을 읽을 때도 사용할 때이 작업을 수행해야합니다 System.in. 이 공백 구분 기호를지나 스캐너를 진행하려면를 사용 scanner.nextLine()하여 줄 구분 기호를 지워야합니다. 참조 : scanner.nextLine () 사용


부록:

LinePattern다음 Pattern과 일치 하는 a로 정의됩니다 .

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}+");

The reason is that hasNext() checks if there are any more non-whitespace characters available. hasNextLine() checks to see if there is another line of text available. Your text file probably has a newline at the end of it so it has another line but no more characters that are not whitespace.

Many text editors automatically add a newline to the end of a file if there isn't one already.

In other words, your input file is not this (the numbers are line numbers):

1. a   3   9
2. b   3   6
3. c   3   3
4. d   2   8
5. e   2   5

It is actually this:

1. a   3   9
2. b   3   6
3. c   3   3
4. d   2   8
5. e   2   5
6. 

Short answer

You have an empty line at the end of the file.


Reason for the empty line

If you take your content and save it for example into a txt file, some editors will add an empty new line to your file.

The editors behave this way, because this is part of the POSIX standard:

3.206 Line

A sequence of zero or more non- characters plus a terminating character.

This topic has been discussed in this thread.


Java Scanner documentation

Here is the documentation from the Java 8 Scanner class.

hasNext()

Returns true if this scanner has another token in its input.


hasNextLine()

Returns true if there is another line in the input of this scanner.


Reason for the Java code behavior

Because of the above described facts, hasNextLine() will return true, but hasNext() cannot find anything, which it can recognize as Token and returns therefore false.

For additional infos see durron597 post.


You are consuming the value of next(), but asking for hasNext() and hasNextLine(). next(), per default, returns everything to the next whitespace(). So you are iterating through all whitespace seperated strings, and after each of them you are asking about the nextLine().

i 1 1 -> hasNextLine()? True. hasNext()? Also true.

1 1 -> hasNextLine()? True. hasNext()? Also true (still a whitespace left)

1 -> hasNextLine()? True (Line Seperator, probably). haxNext? False, no whitespace anymore.


The Basic concept of hasNext() and hasNextLine() is

hasNextLine:- Returns true if there is another line in the input of this scanner. This method may block while waiting for input. The scanner does not advance past any input.

Returns: true if and only if this scanner has another line of input Throws: IllegalStateException - if this scanner is closed

hasNext

Returns true if the next complete token matches the specified pattern.

A complete token is prefixed and postfixed by input that matches the delimiter pattern. This method may block while waiting for input. The scanner does not advance past any input.

Parameters: pattern - the pattern to scan for

Returns: true if and only if this scanner has another token matching the specified pattern

Since your last input saying true for nextLine() because A call to scan.nextLine(); returns the next token. It's important to note that the scanner returns a space and a letter, because it's reading from the end of the last token until the beginning of the next line.

참고URL : https://stackoverflow.com/questions/31993377/why-is-hasnext-false-but-hasnextline-is-true

반응형