[java] next () 또는 nextFoo ()를 사용한 후 스캐너가 nextLine ()을 건너 뛰고 있습니까?

내가 사용하고 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()내가 그들이 원하는대로 실행됩니다.



답변

Scanner.nextInt메소드가 “Enter”키를 눌러 작성된 입력에서 개행 문자를 읽지 않기 때문에 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();
    

답변

문제는 input.nextInt () 메소드에 있습니다. int 값만 읽습니다. 따라서 input.nextLine ()을 계속 사용하면 “\ n”Enter 키가 나타납니다. 따라서 이것을 건너 뛰려면 input.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();


답변

당신이 다음을 눌러 숫자를 입력 할 때 때문입니다 Enter, input.nextInt()수만이 아니라 “줄의 끝을”소비한다. input.nextLine()실행될 때 첫 번째 입력에서 여전히 버퍼에있는 “end of line”을 사용합니다.

대신에 input.nextLine()바로 사용 하십시오input.nextInt()


답변

이 문제와 관련하여 많은 질문이있는 것 같습니다 java.util.Scanner. 더 읽기 쉽고 관용적 인 해결책은 전화 scanner.skip("[\r\n]+")한 후 개행 문자를 삭제 하기 위해 전화 하는 것 nextInt()입니다.

편집 : @PatrickParker가 아래에 언급했듯이 사용자가 숫자 뒤에 공백을 입력하면 무한 루프가 발생합니다. skip과 함께 사용하기에 더 나은 패턴에 대한 답변을 보려면 https://stackoverflow.com/a/42471816/143585


답변

input.nextInt();개행을 캡처하지 않기 때문에 그렇게합니다. input.nextLine();아래 에 추가하여 제안 된 다른 사람들처럼 할 수 있습니다.
또는 C # 스타일로 nextLine을 정수로 구문 분석 할 수 있습니다.

int number = Integer.parseInt(input.nextLine()); 

이 작업을 수행해도 코드가 줄어 듭니다.


답변

TL; DR scanner.skip("\\R")scanner.newLine()호출 전에 사용 하며 다음 후에 실행됩니다.

  • scanner.next()
  • scanner.next*TYPE*() 방법.

알아야 할 사항 :

  • 몇 줄을 나타내는 텍스트에는 줄 사이에 인쇄 할 수없는 문자도 포함됩니다 (우리는 줄 구분 기호라고 부릅니다)

    • 캐리지 리턴 (으로 표시되는 문자열 리터럴에서 CR- "\r")
    • 줄 바꿈 (LF-로 표시되는 문자열 리터럴 "\n")
  • 콘솔에서 데이터를 읽을 때, 그것은 자신의 응답을 입력 할 수있는 사용자를 허용하고 그는이 완료되면 그가 할 필요가 어떻게 든 그 사실을 확인합니다. 그렇게하려면, 사용자는 키보드에서 “enter”/ “return”키를 눌러야합니다.

    중요한 것은 사용자 데이터를 표준 입력 (로 표시되는 System.in것으로 표시)에 배치하는 것 외에도이 키 Scanner는 OS 종속 행 구분 기호 (Windows와 같은)를 전송 \r\n합니다.

    따라서 사용자에게와 같은 값을 요구할 때 age사용자 유형 42와 Enter 키를 누르면 표준 입력에 포함 "42\r\n"됩니다.

문제

Scanner#nextInt(및 기타 방법)에서는 스캐너가 이러한 행 구분 기호 를 사용할 수 없습니다 . 그것은에서 읽을 것이다 (대표 사용자로부터 더 이상 자리가 있다는 것을 알고 얼마나 다른 스캐너 표준 입력에서 제거 할 공백에 직면 이상의 값?), 그러나 그것은 또한 것이다 캐시 내부적으로 그 라인 분리를 . 우리가 기억해야 할 것은 모든 스캐너 메소드가 항상 캐시 된 텍스트부터 스캔한다는 것입니다. Scanner#nextTypeSystem.inage

이제 줄 구분 기호 (또는 스트림 끝)를 찾을 때까지Scanner#nextLine() 모든 문자를 수집하고 반환합니다 . 그러나 콘솔에서 숫자를 읽은 후 줄 구분 기호는 스캐너의 캐시에서 즉시 발견되므로 빈 문자열을 반환합니다. 즉, 줄 구분 기호 (또는 스트림 끝) 앞에 스캐너가 문자를 찾을 수 없습니다.
BTW 또한 소비 하는 라인 분리합니다.
nextLine

해결책

그래서 당신의 결과로 그 빈 문자열을 피하면서 전체 라인 다음 번호를 요청하고 싶을 때 nextLine중,

  • nextInt스캐너 캐시에서 남은 줄 구분 기호 를
    • 전화 nextLine,
    • 또는 IMO 더 읽기 쉬운 방법은 호출 skip("\\R")하거나 skip("\r\n|\r|\n")스캐너가 줄 구분 기호와 일치하는 부분을 건너 뛰도록 하는 것입니다 (자세한 정보 \R: https : //.com/a/31060125 )
  • nextInt( next또는 다른 nextTYPE방법)을 전혀 사용하지 마십시오 . 대신 nextLine각 행의 번호를 사용하여 한 줄씩 전체 데이터를 읽고 (한 줄에 하나의 숫자 만 있다고 가정) intvia 와 같은 적절한 유형으로 구문 분석하십시오 Integer.parseInt.

BTW : 메소드는 다음에 구분되지 않는 값 (토큰)을 찾을 때까지 스캐너에 의해 캐시 된 것을 포함하여 구분 기호 (기본적으로 탭, 줄 구분 기호와 같은 모든 공백)를 건너 뛸 수 있습니다 . 코드 와 같은 입력을위한 덕분입니다Scanner#nextType"42\r\n\r\n321\r\n\r\n\r\nfoobar"

int num1 = sc.nextInt();
int num2 = sc.nextInt();
String name = sc.next();

제대로 할당 할 수 있습니다 num1=42 num2=321 name=foobar.


답변

대신에 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();
}