# Scanner 입력

## Scanner 사용 입력 처리

이 문서에서는 `Scanner`를 이용하여 `System.in`에 대한 입력을 처리하는 방법에 대해서 다룬다.

### Scanner

`Scanner`는 java.util 패키지에 있어서 기본적으로 지원되는 도구가 아니다. 또한 스캐너의 주 목적은 `System.in`에 대한 입력을 처리하는 것이 아니라 **문자열의 패턴 분석**도구이다. 이를 표준 입력에 적용시켜도 잘 작동하기 때문에 자바에서 표준 입력을 처리할 때 `Scanner`를 많이 사용한다. `Scanner`는 `System.in`에서 입력되는 글자들을 모아 원하는 패턴에 맞게 입력받는 역할을 수행한다.

### Scanner 생성

`Scanner`는 기본적으로 지원되는 도구가 아니기 때문에 사용하기 위해서는 생성이라는 과정을 거친다. 생성 코드는 다음과 같다.

```java
Scanner sc = new Scanner(System.in);
```

아직 **객체 생성**을 배우지 않았기 때문에 간략하게 살펴보면 다음과 같다.

* Scanner : 도구의 보관 형태(자료형)을 말한다.
* sc : 제어를 위해 만든 참조 변수의 이름이다. 참조 변수는 리모컨의 형태라고 이해하면 된다.
* new : 신규 도구 생성 키워드이다. 바로 뒤에 있는 대상을 생성한다.
* Scanner(System.in) : `Scanner`를 만들면서 `System.in`의 정보를 알려주어 결합하겠다는 뜻이다.

### Scanner 종료

Scanner처럼 입력을 위한 도구를 만든 경우 메모리 관리를 위하여 반드시 사용 후 종료를 해야 한다. 이는 마치 컴퓨터를 사용하고 나서 전원을 끄는 것과 마찬가지로, 프로그램 내에서 메모리를 효율적으로 관리할 수 있는 방법 중 하나이다.

```java
sc.close();
```

여기서 sc는 만들 때 지어둔 변수임에 유의한다. 변수명이 다르면 sc 자리에 해당 변수명이 위치하게 된다.

### Scanner 사용

Scanner를 이용하여 사용자가 입력하는 다양한 형태의 값을 입력받을 수 있다.

* 단어 입력 : .next()
* 한줄 입력 : .nextLine()
* 정수 입력 : .nextInt(), .nextLong(), .nextByte(), .nextShort()
* 실수 입력 : .nextFloat(), .nextDouble()
* 논리 입력 : .nextBoolean()

#### Scanner 입력값 구분 기준

사용자가 다음과 같은 값을 입력했다고 가정해본다.

```
학교종이 땡땡땡 어서모이자
선생님이 우리를 기다리신다
```

띄어쓰기는 아스키코드 `32`번이며, 개행은 아스키코드`10`번이므로 실제 컴퓨터에는 다음과 같은 값이 전달된다. (개행은 운영체제에 따라 전달되는 값이 다르며, `\13\10`형태로 들어올 수 있다)

```
학교종이\32땡땡땡\32어서모이자\10선생님이\32우리를\32기다리신다\10
```

위의 입력형태를 놓고 생각한다면, 우리가 알고 있는 띄어쓰기나 엔터 등도 하나의 값을 가지기 때문에 단어와 한줄은 다음과 같이 생각해볼 수 있다.

* 단어 : NULL(0), NewLine(10), Space(32) 등 공백이 발생하기 전까지의 값
* 한줄 : NULL(0), NewLine(10)이 발생하기 전까지의 값

NULL은 `없음`을 나타내는 값이기 때문에 만약 NULL이 발생해도 공백으로 간주할 수 있다.

#### 단어 입력

```java
String str = sc.next();
```

편의상 단어라고 부르기는 하지만 정확히 이야기하면 **공백이 발생하기 전까지 입력한 글자**를 말한다. 위에서 살펴본 예제를 통해서 단어 입력이 어떤식으로 이루어지는지 살펴본다

```
학교종이\32땡땡땡\32어서모이자\10선생님이\32우리를\32기다리신다\10
```

단어 입력을 한 번 수행하면 다음과 같은 내용이 남게 된다.

```
\32땡땡땡\32어서모이자\10선생님이\32우리를\32기다리신다\10
```

다음 단어 입력을 수행하게 되면 시작하자마자 Space(32)가 나오게 되는데 이런 경우 이전 입력에서 남은 값으로 간주하여 버리고 다음 값을 읽게 된다.

```
\32어서모이자\10선생님이\32우리를\32기다리신다\10
```

이런 식으로 계속해서 입력 받을 수 있다.

```
\10선생님이\32우리를\32기다리신다\10
```

```
\32우리를\32기다리신다\10
```

```
\32기다리신다\10
```

```
\10
```

더이상 입력받을 내용이 없을 경우에는 오류가 발생한다.

```java
import java.util.*;//Scanner를 위한 import
public class ScannerWordInput {
    public static void main(String[] args){
        //도구 생성
        Scanner sc = new Scanner(System.in);
        
        //단어 입력
        String a = sc.next();
        String b = sc.next();
        String c = sc.next();
        String d = sc.next();
        String e = sc.next();
        String f = sc.next();
        
        //출력
        System.out.println(a);
        System.out.println(b);
        System.out.println(c);
        System.out.println(d);
        System.out.println(e);
        System.out.println(f);
        
        //도구 정리
        sc.close();
    }
}
```

실행한 다음 다음과 같이 입력하여 출력 결과를 살펴보면 이해할 수 있다.

```
동해물과 백두산이 마르고닳도록
하느님이 보우하사 우리나라만세
```

#### 한 줄 입력

```java
String str = sc.nextLine();
```

줄 전체를 입력받고 싶은 경우에는 Space(32)는 고려 대상이 아니게 된다. 따라서 NULL(0) 또는 NewLine(10)을 발견하기 전까지 입력받은 내용을 문자열 변수에 저장하게 된다.

```
학교종이\32땡땡땡\32어서모이자\10선생님이\32우리를\32기다리신다\10
```

위의 값에서 한줄 입력을 수행하고 난 후 남은 데이터는 다음과 같다.

```
선생님이\32우리를\32기다리신다\10
```

단어 입력 부분과 유심히 비교해보면 차이점이 있는데, NewLine(10)에 해당하는 값인 \10을 버린다는 것이다. 이렇게 단어 입력과 한줄 입력의 차이점이 존재하기 때문에 혼용할 경우 주의사항이 발생하게 된다.

한 번 더 입력을 받으면 모든 값이 입력 완료된다.

#### 정수 입력

```java
int num = sc.nextInt();
```

정수 입력은 단어 입력 후 입력값을 숫자로 변환한 것과 같다. 중요한 것은 한 줄 입력은 아니라는 것이며, 왜 그런지에 대해서는 다음 값을 보면 이해할 수 있다.

```
111 222 333 
444 555
```

누군가가 `위의 글자 중 숫자가 몇 개인가?`라고 물어봤을 때 우리는 망설이지 않고 5개라고 대답할 것이다. 숫자의 경우도 공백을 기준으로 구분된다는 것을 의미하며, 이는 단어 입력의 방식과 동일하다.

변환 명령만 알면 다음과 같이 표현할 수도 있다.

```java
String str = sc.next();
int num = Integer.parseInt(str);
```

하지만 `nextInt` 명령을 이용하면 한 줄로 처리가 되므로 쉽게 이용할 수 있다.

int 외의 정수들은 다음과 같이 입력받으며, 이용방법은 동일하다.

```java
byte a = sc.nextByte();
short b = sc.nextShort();
long c = sc.nextLong();
```

#### 실수 입력

실수도 정수와 마찬가지로 단어 입력과 동일하게 진행된다. 실수는 두 종류가 있으며, 각각에 대한 명령은 다음과 같다.

```java
float a = sc.nextFloat();
double b = sc.nextDouble();
```
