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



6 Answers

문제는 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();
Question

나는 입력을 읽기 위해 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() 이 실행되도록합니다.




문제를 피하려면 nextLine(); nextInt(); 직후 nextInt(); 버퍼를 지우는 데 도움이됩니다. Enter 키를 누르면 nextInt(); 새 행을 캡처하지 않으므로 나중에 Scanner 코드를 건너 뜁니다.

Scanner scanner =  new Scanner(System.in);
int option = scanner.nextInt();
scanner.nextLine(); //clearing the buffer



파티에 꽤 늦은 것 같아.

앞에서 설명한 것처럼 int 값을 얻은 후에 input.nextLine() 을 호출 input.nextLine() 문제가 해결됩니다. 귀하의 코드가 작동하지 않는 이유는 귀하가 입력 한 곳 (int를 입력 한 곳)에서 string1 에 저장할 다른 것이 없기 때문입니다. 전체 주제에 대해 좀 더 자세히 설명하겠습니다.

Scanner 클래스의 nextFoo () 메서드 중에서 oddLine () 이 이상한 것으로 간주합니다. 간단한 예를 들어 봅시다. 다음과 같은 두 줄의 코드가 있다고 가정 해 보겠습니다.

int firstNumber = input.nextInt();
int secondNumber = input.nextInt();

아래에 값을 입력하면 (한 줄의 입력으로)

54 234

firstNumbersecondNumber 변수의 값은 각각 54와 234가됩니다. 이 방법이 작동하는 이유는 nextInt () 메서드가 값을 가져올 때 새 줄 바꿈 ( 즉, \ n )이 자동으로 생성 되지 않기 때문입니다. 단순히 "다음 int" 를 가져와 계속 진행합니다. nextLine ()을 제외한 나머지 nextFoo () 메소드에서도 마찬가지입니다.

nextLine ()은 값을 취한 후 바로 새 줄 바꿈을 생성합니다. 이것은 @RohitJain이 새로운 라인 피드가 "소비"되었다는 것을 의미합니다.

마지막으로 next () 메서드는 새로운 라인 생성 하지 않고 가장 가까운 String 취합니다. 이렇게하면 동일한 단일 행 내에서 별도의 String을 가져 오는 우대 방법이됩니다.

나는 이것이 도움이되기를 바랍니다 .. 즐거운 코딩!




public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        int i = scan.nextInt();
        scan.nextLine();
        double d = scan.nextDouble();
        scan.nextLine();
        String s = scan.nextLine();

        System.out.println("String: " + s);
        System.out.println("Double: " + d);
        System.out.println("Int: " + i);
    }



문자열과 int를 모두 읽으려는 경우 해결 방법은 두 개의 스캐너를 사용하는 것입니다.

Scanner stringScanner = new Scanner(System.in);
Scanner intScanner = new Scanner(System.in);

intScanner.nextInt();
String s = stringScanner.nextLine(); // unaffected by previous nextInt()
System.out.println(s);

intScanner.close();
stringScanner.close();



java.util.Scanner 하면이 문제에 대해 많은 질문이있는 것 같습니다. nextInt() 호출 한 후에 개행 문자를 삭제하려면 scanner.skip("[\r\n]+") 을 호출하는 것이 더 읽기 쉽거나 관용적 인 해결책이라고 생각합니다.

편집 : @ PatrickParker 아래에 명시된 바와 같이, 사용자가 숫자 뒤에 공백을 입력하면 무한 루프가 발생합니다. 건너 뛰기와 함께 사용하는 더 좋은 패턴에 대한 답변보기 : https://.com/a/42471816/143585




알아야 할 사항 :

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

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

    중요한 것은 표준 입력 (사용자가 Scanner 읽는 System.in 표시)에 사용자 데이터를 배치하는 것 외에이 키가 Windows 의존성 줄 구분 기호 (예 : Windows \r\n )를 보낸다는 것입니다.

    따라서 age 과 같은 가치를 묻는 사용자 유형 42 및 프레스 입력시 표준 입력에는 "42\r\n" 됩니다.

문제

Scanner#nextInt (및 다른 Scanner#next Type 메서드)는 스캐너가 이러한 행 구분 기호를 사용 하지 못하도록합니다. 그것은 System.in 에서 읽을 것입니다 (Scanner는 공백 문자보다 age 값을 나타내는 사용자의 숫자가 더 이상 없음을 어떻게 알 수 있습니까?) 표준 입력에서이를 제거하지만 내부적으로 해당 행 구분 기호도 캐시 합니다 . 우리가 기억해야 할 것은 모든 스캐너 메서드가 항상 캐시 된 텍스트부터 검색한다는 것입니다.

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

해결책

따라서 숫자를 물어보고 전체 라인을 요구할 때 nextLine 결과로 빈 문자열을 피하려면

  • nextInt 다음에 스캐너 캐시에서 행 구분 기호를 사용하기 위해 nextLine 추가로 호출하면,
  • nextInt (또는 next , 또는 nextTYPE 메소드)를 전혀 사용하지 마십시오. 대신 nextLine 사용하여 전체 데이터를 읽고 각 행의 숫자 (한 줄만 포함)가 Integer.parseInt 를 통해 int 와 같은 적절한 유형으로 파싱 Integer.parseInt .

BTW : Scanner#next Type 메서드는 구분 기호 ( Scanner#next Type 과 같은 비 구분 기호 값 (토큰)을 찾을 때까지 스캐너로 캐시 된 것을 포함하여 구분선 (기본적으로 탭, 줄 구분 기호와 같은 모든 공백)을 건너 뛸 수 있습니다. "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 를 올바르게 지정할 수 있습니다.




Related