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


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() 이 실행되도록합니다.




파티에 꽤 늦은 것 같아.

앞에서 설명한 것처럼 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을 가져 오는 우대 방법이됩니다.

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




문자열과 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();



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



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

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



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 를 올바르게 지정할 수 있습니다.