본문 바로가기
Java/Java

Scanner 클래스란?, next()메소드, nextLine()메소드

by 박채니 2022. 3. 1.
SMALL

안녕하세요, 코린이의 코딩 학습기 채니 입니다.

 

개인 포스팅용으로 내용에 오류 및 잘못된 정보가 있을 수 있습니다.


java.util 패키지의 Scanner 클래스에 대해서 알아보도록 하겠습니다.

 

Scanner클래스란?

- 사용자의 키보드 입력 값을 읽어오는 객체

 

Scanner클래스를 사용하기 위해선 객체를 생성하고, 다른 패키지 내에 있는 클래스 사용이므로 import를 해줘야겠죠?

package com.ce.java;

import java.util.Scanner;

public class ScannerStudy {
	public static void main(String[] args) {
		ScannerStudy study = new ScannerStudy();
		study.test1();
	}
	
	public void test1() {
		//Scanner 객체 생성
		Scanner sc = new Scanner(System.in);
	}
}

위와 같이 객체 생성, import를 해주었습니다.

Scanner 객체 내에 System.in 이라는 인자 값을 전달해주었습니다. (System.in을 입력 받아서 Scanner에게 전달)

※ System.in이란?

- 표준 입력

- Scanner에서는 키보드의 입력을 읽어들일 수 있는 객체

 

Scanner 메소드 종류

① next 계열 메소드 

  - next()

  - nextInt()

  - nextDouble()

  - nextBoolean

  등등... (단, nextChar()는 없음)

 

객체명.next를 해보면 각 메소드 별로 어떠한 타입으로 받아야하는 지 나와있습니다.

② nextLine 계열 메소드 

  - nextLine()

 


next() 메소드 활용하기


문자열을 입력 받아 리턴하였을 때 :

public void test1() {
	//Scanner 객체 생성
	Scanner sc = new Scanner(System.in);

	System.out.print("> 이름을 입력하세요 : ");
	String name = sc.next();
	System.out.printf("안녕하세요~ %s님!\n", name);
		
	System.out.print("> 무슨 공부 중이세요? : ");
	String subject = sc.next();
	System.out.printf("아~ %s 공부 중이시군요! 힘내세요..\n", subject);
 }
 
 @콘솔출력값
> 이름을 입력하세요 : 박채니
안녕하세요~ 박채니님!
> 무슨 공부 중이세요? : 자바
아~ 자바 공부 중이시군요! 힘내세요..

입력 받은 값을 String으로 저장하여 printf문을 사용해 위와 같이 출력하였습니다.

 

정수/실수/boolean/char를 입력 받아 리턴하였을 때 :

public void test1() {
	System.out.print("> 나이를 입력하세요 : ");
	int age = sc.nextInt();	//사용자 값을 읽어서 정수형으로 변환
	System.out.printf("%d살이시군요!\n", age);
		
	System.out.print("> 키를 입력하세요 (예:177.8) : ");
	double height = sc.nextDouble();
	System.out.printf("키가 %.1fcm이시군요!\n", height);
		
	System.out.print("> 결혼하셨나요? (true|false) : ");
	boolean marry = sc.nextBoolean();
	System.out.printf("결혼여부는 %b이시군요!\n", marry);
		
	System.out.print("> 성별을 입력하세요 (여자|남자) : ");
	char gender = sc.next().charAt(0);
	System.out.printf("성별은 %c자시군요!\n", gender);
}

@콘솔출력값
> 나이를 입력하세요 : 24
24살이시군요!
> 키를 입력하세요 (예:177.8) : 165.7
키가 165.7cm이시군요!
> 결혼하셨나요? (true|false) : false
결혼여부는 false이시군요!
> 성별을 입력하세요 (여자|남자) : 여자
성별은 여자시군요!

키보드 입력 값은 반드시 문자열로 읽어 오기 때문에 각 next메소드에 따라 정수형/실수형/불리언형 등으로 변환하여 반환해줍니다.

또한 next메소드 내에는 nextChar, 즉 char 문자형으로 받아올 수 있는 메소드가 없습니다.

다만, 단 하나의 문자를 받아오는 경우가 빈번할텐데 그럴 땐 charAt()메소드를 사용하여 원하는 값을 리턴해줄 수 있습니다.

※ charAt(인덱스번호) - 인덱스 번호는 0번부터 시작 / 문자열 중 0번째에 있는 문자형을 리턴해줌

여자를 입력하였지만, 문자열 중 0번째 문자만 리턴하였으므로 '여'만 출력

만일 next().charAt(1)이면 '자'를 출력!

 

 

nextLine() 메소드 활용하기

활용에 앞서 next() 와 nextLine() 모두 String을 받는 메소드인데 어떠한 차이점이 있는 지 알아 보겠습니다.

 

next() 메소드를 활용하여 주소를 입력받아 리턴해보았습니다.

public void test2() {
	Scanner sc = new Scanner(System.in);
	
	System.out.print("> 주소를 입력하세요 : ");
	String addr = sc.next();
	System.out.printf("주소 : %s\n", addr);	
}

@콘솔출력값
> 주소를 입력하세요 : 서울시 송파구
주소 : 서울시

사용자는 "서울시 송파구" 를 입력하였는데 리턴 값은 "서울시"인 걸 확인할 수 있습니다.

 

그렇다면 nextLine() 메소드는 어떠할까요?

동일한 코드지만 sc.nextLine()으로 값을 입력 받아보았습니다.

public void test2() {
	Scanner sc = new Scanner(System.in);
	
	System.out.print("> 주소를 입력하세요 : ");
	String addr = sc.nextLine();
	System.out.printf("주소 : %s\n", addr);
}
    
@콘솔출력값
> 주소를 입력하세요 : 서울시 송파구
주소 : 서울시 송파구

입력 받은 그대로 "서울시 송파구"로 리턴한 것을 확인할 수 있습니다.

 

next()메소드와 nextLine()메소드 차이점

 - next()메소드

   ☞ 실제 값 이후 공백 / 개행 문자 전까지만 읽어옴

 - nextLine() 메소드

   ☞ 실제 값 이후 개행 문자(Enter)까지 읽어온 후 개행 문자를 버리고 리턴

 

next()메소드와 nextLine()메소드 공통점

- 실제 값 이전에 만난 공백 / 개행 문자는 무시!!

 

이러한 차이점 때문에 같은 코드이지만 다른 리턴 값을 가져옵니다.

 

 

next() 계열 메소드 + nextLine 메소드 혼합하여 활용하기

 

이름은 next()메소드로, 주소는 nextLine 메소드로 받아서 리턴해보았습니다.

public void test2() {
	Scanner sc = new Scanner(System.in);
		
	System.out.print("> 이름을 입력하세요 : ");
	String name = sc.next();
	
	System.out.print("> 주소를 입력하세요 : ");
	String addr = sc.nextLine();
	
	System.out.printf("이름 : %s\n", name);
	System.out.printf("주소 : %s\n", addr);
}
    
@콘솔출력값
> 이름을 입력하세요 : 박채니
> 주소를 입력하세요 : 이름 : 박채니
주소 :

 

다만, 위와 같이 이름 입력 후 엔터를 누르니 이상하게 값이 출력되었습니다.

 

이를 해결하고자 next()메소드 사용 후 개행문자 날리기 용으로 nextLine()메소드를 사용하였습니다.

 

public void test2() {
	Scanner sc = new Scanner(System.in);
		
	System.out.print("> 이름을 입력하세요 : ");
	String name = sc.next();
		
	sc.nextLine();	// 개행문자 날리기용
	
	System.out.print("> 주소를 입력하세요 : ");
	String addr = sc.nextLine();
	
	System.out.printf("이름 : %s\n", name);
	System.out.printf("주소 : %s\n", addr);
}

@콘솔출력값
> 이름을 입력하세요 : 박채니
> 주소를 입력하세요 : 서울시 송파구
이름 : 박채니
주소 : 서울시 송파구

 

next() 계열 메소드 사용 후 nextLine()메소드 사용 시 반드시 개행문자 날리기용 (nextLine)을 입력해줘야합니다.

 

그 이유는?

실제론 키보드의 입력 값을 바로 Scanner가 읽어오고 JVM이 실행하는 것이 아니라,

키보드의 입력 값은 input buffer(입력 버퍼)로 전달 되고 입력 버퍼에 있는 값들을 읽어와서 실행하는 것입니다.

 

따라서 박채니(엔터)를 하면 input butter에 박채니\n 값이 입력 되고 그 값들을 각 메소드들을 사용해 읽어옵니다.

 

next() 계열 메소드의 경우, 공백/개행 문자 전!!까지 값을 읽어온다는 특징으로 인해 "박채니"만 읽어가고 "\n"는 버퍼에 남겨둡니다.

그 후 nextLine() 메소드로 값을 읽어오려고 하니 버퍼에 "\n"이 입력 되어있으므로 개행문자를 읽어오고 버린 후 " " 를 출력하게 됩니다.

(실제 값 이전 공백/개행 무시, 개행문자까지 리턴 후 버리는 특징)

따라서 리턴 값이 엉망진창이 되었던 것이죠!!

 

이를 방지하기 위하여 nextLine()으로 남아있던 개행문자(\n)를 버려주게 되면,

버퍼는 텅텅 비기 때문에 다음 nextLine 혹은 next메소드가 호출 됐을 때 값 입력을 기다리고 읽어오게 되는 것입니다.

 

 

 

 

LIST