스캐너가 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
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()
실행될 때 첫 번째 입력에서 버퍼에있는 "줄 끝"을 사용합니다.
대신, 사용 input.nextLine()
하십시오input.nextInt()
이 문제에 대한 많은 질문이있는 것 java.util.Scanner
입니다. 더 읽기 제출 관용적 인 해결책은을 호출 scanner.skip("[\r\n]+")
한 후 줄 바꿈 문자를 삭제 하도록 호출 하는 것 nextInt()
입니다.
편집 : @PatrickParker가 아래에 언급했듯이 사용자가 숫자 공백을 입력하면 무한 루프가 발생합니다. 건너 뛰기와 함께 사용할 더 나은 패턴에 대한 답변을 참조하십시오 : https://stackoverflow.com/a/42471816/143585
input.nextInt();
개행을 계획하지 않기 때문에 그렇게합니다. input.nextLine();
아래 에 추가하여 제안한 다른 사람들처럼 할 수 있습니다.
또는 다음과 같이 C # 스타일을 수행하고 nextLine을 정수로 구문 분석 할 수 있습니다.
int number = Integer.parseInt(input.nextLine());
이렇게하면 똑같이 작동하며 코드 한 줄을 절약 할 수 있습니다.
알아야 할 사항 :
다음과 같이 줄 사이에 인쇄 할 수없는 문자 (우리는 줄 구분 기호라고 함)도 포함됩니다.
- 캐리지 리턴 (CR-로 표현되는 표현되는 리터럴에서
"\r"
) - 줄 바꿈 (LF-로 표시되는 리터럴에서
"\n"
)
- 캐리지 리턴 (CR-로 표현되는 표현되는 리터럴에서
콘솔에서 데이터를 읽을 때 사용자는 자신의 응답을 입력 할 수 있으며 완료 되면 어떻게 든 그 사실을 확인 해야합니다 . 이를 위해 사용자는 키보드에서 "enter"/ "return"키를 누르십시오.
중요한 것은 데이터를 표준 입력 (
System.in
로Scanner
표시됨)에 배치하는 것 외에이 키가 그\r\n
자체 OS 존재 줄 구분 기호 (예 : Windows )를 전송한다는 것입니다.따라서 사용자에게와 같은 값을 요청하고 사용자가
age
42를 입력하고 키를 입력 표준 입력에 입력"42\r\n"
합니다.
문제
Scanner#nextInt
(기타 및 방법)가 스캐너 이러한 줄 구분 기호 를 사용하는 것을 허용하지 않습니다 . 그것은에서 읽을 것이다 (user-로부터 더 대표 이상 자리가 있다는 것을 알고 얼마나 다른 스캐너 표준 입력 입력에서 제거 할 공백에 직면 이상의 값?), 그러나 그것은 또한 것이다 캐시 내부적으로 그 라인 분리를 . 기억해야 할 것은 모든 스캐너 메소드가 항상 캐시 된 텍스트에서 시작하여 스캔한다는 것입니다.Scanner#nextType
System.in
age
이제 줄 구분 기호 (또는 스트림 끝)를 사용할 때까지Scanner#nextLine()
모든 문자를 수집하고 반환합니다 . 그러나 콘솔에서 번호를 읽은 후 줄 구분 기호는 스캐너의 캐시에서 즉시 발견되기 때문에 읽습니다. 이는 스캐너가 해당 줄 구분 기호 앞의 문자 (또는 스트림 끝)를 의미합니다. BTW 또한 소비 하는 라인 분리합니다.nextLine
해결책
그래서 당신의 결과로 그 빈 번호를 피하면서 전체 라인 다음 번호를 요청하고 싶을 때 nextLine
중,
nextInt
스캐너 캐시에서 남은 줄 구분 기호 사용- 전화
nextLine
, - 또는
skip("\\R")
스캐너가\R
줄 구분 기호를 부분 을 건너 뛰도록 호출 하여 (자세한 정보\R
: https://stackoverflow.com/a/31060125 )
- 전화
nextInt
(next
또는 어떤nextTYPE
방법도) 전혀 사용하지 않습니다 . 전체 데이터를 대신 한 줄씩 읽고nextLine
각 줄의 숫자 (한 줄에 숫자가 하나만 포함되어 있다고 가정 )를int
통해 와 같은 적절한 유형으로 구문 분석합니다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();
}
이전과 정수를 모두 가지고있는 두 개의 스캐너를 사용하는 것이 해결책입니다.
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();
를 방지 문제 하려면 버퍼를 지우는 데 도움이되는 nextLine();
즉시 사용 하십시오 nextInt();
. 이 누르면 당신 ENTER
는 nextInt();
새로운 라인을 캡처하고 따라서 생략하지 않습니다 Scanner
나중에 코드를.
Scanner scanner = new Scanner(System.in);
int option = scanner.nextInt();
scanner.nextLine(); //clearing the buffer
스캐너 클래스 nextLine () 메소드와 혼동하지 않고 신속하게 입력을 스캔 사용자 정의 입력 스캐너를 사용하십시오.
코드 :
class ScanReader {
/**
* @author Nikunj Khokhar
*/
private byte[] buf = new byte[4 * 1024];
private int index;
private BufferedInputStream in;
private int total;
public ScanReader(InputStream inputStream) {
in = new BufferedInputStream(inputStream);
}
private int scan() throws IOException {
if (index >= total) {
index = 0;
total = in.read(buf);
if (total <= 0) return -1;
}
return buf[index++];
}
public char scanChar(){
int c=scan();
while (isWhiteSpace(c))c=scan();
return (char)c;
}
public int scanInt() throws IOException {
int integer = 0;
int n = scan();
while (isWhiteSpace(n)) n = scan();
int neg = 1;
if (n == '-') {
neg = -1;
n = scan();
}
while (!isWhiteSpace(n)) {
if (n >= '0' && n <= '9') {
integer *= 10;
integer += n - '0';
n = scan();
}
}
return neg * integer;
}
public String scanString() throws IOException {
int c = scan();
while (isWhiteSpace(c)) c = scan();
StringBuilder res = new StringBuilder();
do {
res.appendCodePoint(c);
c = scan();
} while (!isWhiteSpace(c));
return res.toString();
}
private boolean isWhiteSpace(int n) {
if (n == ' ' || n == '\n' || n == '\r' || n == '\t' || n == -1) return true;
else return false;
}
public long scanLong() throws IOException {
long integer = 0;
int n = scan();
while (isWhiteSpace(n)) n = scan();
int neg = 1;
if (n == '-') {
neg = -1;
n = scan();
}
while (!isWhiteSpace(n)) {
if (n >= '0' && n <= '9') {
integer *= 10;
integer += n - '0';
n = scan();
}
}
return neg * integer;
}
public void scanLong(long[] A) throws IOException {
for (int i = 0; i < A.length; i++) A[i] = scanLong();
}
public void scanInt(int[] A) throws IOException {
for (int i = 0; i < A.length; i++) A[i] = scanInt();
}
public double scanDouble() throws IOException {
int c = scan();
while (isWhiteSpace(c)) c = scan();
int sgn = 1;
if (c == '-') {
sgn = -1;
c = scan();
}
double res = 0;
while (!isWhiteSpace(c) && c != '.') {
if (c == 'e' || c == 'E') {
return res * Math.pow(10, scanInt());
}
res *= 10;
res += c - '0';
c = scan();
}
if (c == '.') {
c = scan();
double m = 1;
while (!isWhiteSpace(c)) {
if (c == 'e' || c == 'E') {
return res * Math.pow(10, scanInt());
}
m /= 10;
res += (c - '0') * m;
c = scan();
}
}
return res * sgn;
}
}
장점 :
- BufferReader보다 빠른 입력 스캔
- 시간 감소 감소
- 다음 입력마다 버퍼를 플러시합니다.
방법 :
- scanChar ()-단일 문자 스캔
- scanInt ()-정수 값 스캔
- scanLong () -Long 값 스캔
- scanString ()-문자열 값 스캔
- scanDouble () -Double 값 스캔
- scanInt (int [] array)-전체를 스캔합니다. Array (Integer)
- scanLong (long [] array)-전체 Array (Long) 스캔
사용법 :
- Java 코드 아래에 주어진 코드를 복사하십시오.
- 주어진 클래스에 대한 객체 초기화
ScanReader sc = new ScanReader(System.in);
3. 필요한 클래스 가져 오기 :
import java.io.BufferedInputStream; import java.io.IOException; import java.io.InputStream;
4. 메인 메서드에서 IOException을 던져 예외를 처리합니다. 5. 제공된 메서드를 사용합니다. 6. 즐기십시오
예 :
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
class Main{
public static void main(String... as) throws IOException{
ScanReader sc = new ScanReader(System.in);
int a=sc.scanInt();
System.out.println(a);
}
}
class ScanReader....
sc.nextLine()
입력을 구문 분석하는 것보다 낫습니다. 성능이 현명하기 때문에 좋을 것입니다.
파티에 꽤 늦었 나봐 ..
앞서 언급했듯이 input.nextLine()
int 값을 얻은 후 호출 하면 문제가 해결됩니다. 코드가 작동하지 않는 이유는 입력 (int를 입력 한 위치)에서에 저장할 다른 것이 없기 때문 string1
입니다. 전체 주제에 대해 조금 더 설명하겠습니다.
고려 () 꽵를 중 괴상 한 개로서 nextFoo () 스캐너 클래스 방법. 간단한 예를 들어 보겠습니다. 아래 코드와 같은 두 줄의 코드가 있다고 가정 해 보겠습니다.
int firstNumber = input.nextInt();
int secondNumber = input.nextInt();
아래 값을 입력하면 (한 줄의 입력으로)
54234
우리 firstNumber
와 secondNumber
변수 의 값은 각각 54와 234가됩니다. 이것이 이런 방식으로 작동하는 이유 는 nextInt () 메서드가 값을받을 때 새 줄 바꿈 ( 예 : \ n )이 자동으로 생성 되지 않기 때문 입니다. 단순히 "next int" 를 취하고 계속 진행합니다. nextLine ()을 제외한 나머지 nextFoo () 메서드에 대해서도 동일합니다.
nextLine ()은 값을 취한 직후 새 줄 바꿈을 생성합니다. 이것이 @RohitJain이 새로운 줄 바꿈이 "소비된다"는 의미입니다.
마지막으로 next () 메서드 는 새 줄 을 생성 하지 않고 가장 가까운 문자열 을 가져옵니다 . 이것은 동일한 한 줄 내에서 별도의 문자열을 가져 오기위한 우선적 인 방법이됩니다.
도움이 되었기를 바랍니다 .. 즐거운 코딩!
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);
}
하나 대신 2 개의 스캐너 개체 사용
Scanner input = new Scanner(System.in);
System.out.println("Enter numerical value");
int option;
Scanner input2 = new Scanner(System.in);
option = input2.nextInt();
비어 있지 않은 입력을 기대한다면
public static Function<Scanner,String> scanLine = (scan -> {
String s = scan.nextLine();
return( s.length() == 0 ? scan.nextLine() : s );
});
위의 예에서 사용 :
System.out.println("Enter numerical value");
int option = input.nextInt(); // read numerical value from input
System.out.println("Enter 1st string");
String string1 = scanLine.apply( input ); // read 1st string
System.out.println("Enter 2nd string");
String string2 = scanLine.apply( input ); // read 2nd string
모든 판독에 새 스캐너를 사용하는 것은 어떻습니까? 아래와 같습니다. 이 접근 방식을 사용하면 문제에 직면하지 않습니다.
int i = new Scanner(System.in).nextInt();
참고 URL : https://stackoverflow.com/questions/7056749/scanner-issue-when-using-nextline-after-nextxxx
'ProgramingTip' 카테고리의 다른 글
Android WebView가 터치 이벤트를 소비하는지 확인 (0) | 2020.12.09 |
---|---|
Android에서 개발하는 데 사용할 수있는 프로그래밍 언어는 무엇입니까? (0) | 2020.12.09 |
iOS : HKObserverQuery의 백그라운드 업데이트 완료 사용 (0) | 2020.12.09 |
구체적인 구현이있는 추상 클래스를 스텁하지 않도록 Pex에 지시하는 방법 (0) | 2020.12.09 |
경고 : Visual Paradigm에서 코드 생성에 사용할 수있는 클래스 모델이 없습니다. (0) | 2020.12.09 |