---
# System prepended metadata

title: 표준입출력
tags: [과외(기태)]

---

## 표준입출력이란?

- 표준 입출력이란 프로그램과 시스템 사이의 데이터를 주고받는 인터페이스를 의미한다
- 모든 프로그래밍 언어는 시스템 표준 입출력장치를 제공한다
  - 일반적으로 표준입력장치는 키보드, 표준출력장치는 모니터를 의미한다
- 자바에서는 `java.lang.System` 클래스를 통해 표준 입출력을 제공한다
  - `System.in` : 표준 입력
  - `System.out` : 표준 출력
  - `System.err` : 표준 에러 (붉은색으로 출력)

## 표준 입력

- 자바에서 표준 입력은 `System.in` 을 통해 제공된다
- `System.in.read()` 메소드를 사용하면 표준 입력으로부터 한 바이트씩 읽을 수 있다
  - ASCII 범위 내의 문자는 정상적으로 읽을 수 있다.
  - ASCII 범위 밖의 문자는 읽을 수 없다. (1 바이트만 읽는다)

```java
import java.io.IOException;

public class StandardInputExample {
    public static void main(String[] args) throws IOException {
        int input = System.in.read(); //input에 키 값 입력
        System.out.println("입력값 :" + input);
    }
}
```

### Scanner 클래스를 사용한 표준 입력

- `System.in.read()` 메소드는 한 바이트씩 읽기 때문에 사용하기 불편하다
- 자바에서 표준 입력을 받기 위해서는 `Scanner` 클래스를 사용한다
- `Scanner` 클래스를 사용하면 사용자로부터 문자열, 정수, 실수 등 다양한 타입의 입력을 받을 수 있다.
- `nextLine()` 메소드는 사용자가 입력한 한 줄을 문자열로 반환한다

**Scanner 클래스의 메서드**

| 메서드 | 설명 |
| --- | --- |
| `next()` | 사용자가 입력한 문자열을 공백을 기준으로 구분하여 문자열을 반환한다 |
| `nextLine()` | 사용자가 입력한 한 줄을 문자열로 반환한다 |
| `nextInt()` | 사용자가 입력한 문자열을 정수로 반환한다 |
| `nextDouble()` | 사용자가 입력한 문자열을 실수로 반환한다 |
| `nextBoolean()` | 사용자가 입력한 문자열을 논리값으로 반환한다 |
| `nextByte()` | 사용자가 입력한 문자열을 바이트로 반환한다 |
| `nextFloat()` | 사용자가 입력한 문자열을 실수로 반환한다 |
| `nextLong()` | 사용자가 입력한 문자열을 정수로 반환한다 |
| `nextShort()` | 사용자가 입력한 문자열을 정수로 반환한다 |

```java
import java.util.Scanner;

public class StandardInputExample {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);

        System.out.println("입력:");
        String input = scanner.nextLine();
        System.out.println("입력된 문자열: " + input);

        scanner.close();
    }
}
```

> scanner을 사용한 후에는 `close()` 메소드를 호출하여 사용을 종료해야 한다

## 표준 출력

- 자바에서 표준 출력은 `System.out` 을 통해 제공된다
- 자바는 크게 세 가지 방법으로 표준 출력을 제공한다

| 메서드 | 설명 |
| --- | --- |
| `System.out.println()` | 출력 후 줄 바꿈을 수행 |
| `System.out.print()` | 출력 후 줄 바꿈을 수행하지 않는다 |
| `System.out.printf()` | C언어의 `printf()` 함수와 동일하게 동작한다 |

```java
public class StandardOutputExample {
    public static void main(String[] args) {
        System.out.println("Hello World");
        System.out.print("Hello World");
        System.out.printf("Hello World");
    }
}
```

### 형식 문자열 (Format String)

![](https://hackmd.io/_uploads/SkZjteWYT.png)

- `System.out.printf()` 메소드를 사용하면 형식 문자열을 사용할 수 있다
- 형식 문자열은 `%` 기호와 함께 사용되며, 형식 문자열에 사용된 `%` 기호의 개수와 형식 문자열에 사용된 형식 지정자의 개수는 일치해야 한다

#### 형식 문자열 지정자

- 형식 문자열 지정자는 다음과 같다

| 형식 지정자 | 설명 |
| --- | --- |
| `%d` | 10진수 정수 |
| `%o` | 8진수 정수 |
| `%x` | 16진수 정수 |
| `%f` | 실수 |
| `%e` | 지수 |
| `%c` | 문자 |
| `%s` | 문자열 |
| `%b` | 논리값 |

#### `String.format()` 메소드를 사용한 형식 문자열 사용 예시

```java
public class StandardOutputExample {
    public static void main(String[] args) {
        int age = 20;
        double height = 178.2;
        String name = "홍길동";

        System.out.printf("name: %s, age: %d, height: %e", name, age, height);
    }
}
```

#### 플래그

- 형식 문자열의 출력 형태를 지정하기 위해 플래그를 사용할 수 있다
- 형식 문자열 지정자와 함께 사용되며, 형식 문자열 지정자와 플래그 사이에는 공백이 없어야 한다
  - 형식 문자열 지정자 앞에 위치한다
- 여러 개를 동시에 사용할 수 있다

| 플래그 | 설명 |
| --- | --- |
| `-` | 왼쪽 정렬 |
| `+` | 부호 표시 |
| `0` | 빈 공간을 0으로 채움 |
| `,` | 천 단위 구분자 사용 |
| `(` | 음수 부호를 괄호로 표시 |

#### 형식 문자열과 플래그 사용 예시

```java
public class StandardOutputExample {
    public static void main(String[] args) {
        int age = 20;
        double height = 178.2;
        String name = "홍길동";

        System.out.printf("name: %s, age: %d, height: %e\n", name, age, height);

        System.out.printf("name: %10s, age: %5d, height: %5.2f\n", name, age, height);

        System.out.printf("name: %-10s, age: %-5d, height: %-5.2f\n", name, age, height);

        System.out.printf("age: %d\n", age);

        System.out.printf("age: %+d\n", age);

        System.out.printf("age: %010d\n", age);

        System.out.printf("age: %,d\n", age);

        System.out.printf("age: %(d\n", -age);
    }
}
```

#### `String.format()` 메서드

- `String.format()` 메서드를 사용하면 형식 문자열을 사용할 수 있다
- `String.format()` 메서드는 형식 문자열을 **반환**한다
  - `System.out.printf()` 메서드는 형식 문자열을 **출력**한다

```java
public class StandardOutputExample {
    public static void main(String[] args) {
        int age = 20;
        double height = 178.2;
        String name = "홍길동";

        String str = String.format("name: %s, age: %d, height: %e", name, age, height);
        System.out.println(str);
    }
}
```

## 표준 에러 출력

- 표준 에러란 프로그램 실행 중에 발생하는 오류 메시지를 의미한다
- 외부 환경에서 표준 출력과 에러 출력을 구분할 필요가 있는데, 이를 위해 자바는 표준 에러를 별도로 제공한다
- 자바에서 표준 에러는 `System.err` 을 통해 제공된다
- `System.err` 은 `System.out` 과 동일한 메소드를 제공한다
  - `System.out`과의 차이점이 있다면 `System.err` 은 붉은색으로 출력된다는 점이다

```java
public class StandardErrorExample {
    public static void main(String[] args) {
        System.out.println("표준 출력");
        System.err.println("표준 에러");
    }
}
```

> 표준 출력과 에러 출력은 별도의 스트림을 사용하기 때문에 출력 순서가 보장되지 않는다. 따라서 표준 출력과 에러 출력을 같이 사용하면 출력 순서가 뒤바뀔 수 있다
>
> ```java
> public class StandardErrorExample {
>     public static void main(String[] args) {
>         for(int i =0; i<10; i++){
>             System.out.println(i);
>             System.err.println(i);
>         }
>     }
> }
> ```
