[Go] 03. fmt - 2. 표준입력

2024. 1. 14. 23:10Go

반응형

1. 표준 입력

표준 입력장치(ex. 키보드)로부터 데이터를 입력받는 함수

  • Scan
    • 표준 입력으로부터 값을 입력받습니다.
  • Scanln
    • 표준 입력으로부터 한줄을 읽어서 값을 입력받습니다.
  • Scanf
    • 표준 입력으로부터 서식형태로 값을 입력받습니다.

func Scan(a ...interface{}) (n int, err error)
func Scanln(a ...interface{}) (n int, err error)
func Scanf(format string, a ...interface{}) (n int, err error)

Scan함수는 입력받을 데이터가 들어있는 주소를 인자로 받아서,
입력 성공시 총 입력된 값의 개수를, 실패시에는 error를 반환합니다.

package main

import "fmt"

func main() {
	var a int
	var b int

	n, err := fmt.Scan(&a, &b)
	if err != nil {
		fmt.Println(n, err)
	} else {
		fmt.Println(n, a, b)
	}
}

입력받은 값을 공백으로 구분하여, a, b에 저장하며
입력 중 에러가 발생되지 않는다면, 입력된 데이터의 개수와 각 값을 출력하는 코드입니다.

예를들어, 10 20를 입력할 경우, 아래와 같이 출력되고,

2 10 20

2 hi와 같이 잘못된 데이터타입이 들어와서 에러가 발생했을시, 아래와 같이 에러문구를 함께 출력합니다.

1 expected integer

참고로, 첫번째 입력부터 오류가 발생했을시에는, 정상적으로 입력된 값이 없기 때문에 n이 0이 되기 때문에 0 expected integer를 출력합니다.


package main

import "fmt"

func main() {
	var a string
	var b string

	n, err := fmt.Scanf("%3s%2s", &a, &b)
	if err != nil {
		fmt.Println(n, err)
	} else {
		fmt.Println(n, a, b)
	}
}

abcde입력을, 서식에 맞춰 "abc", "de"로 입력받는것이 가능합니다

2 abc de

2. Scan 함수 동작 원리

사용자가 표준입력장치(ex. 키보드)로 입력하면, 입력데이터는 standard input stream(표준 입력 스트림, 컴퓨터 내부 메모리 공간)에 저장됩니다.

Scan함수는 표준입력 스트림으로부터 값을 읽어서 입력값을 처리합니다.

stream이라는 말에서 알 수 있듯, 데이터 흐름을 의미하며, 이 값은 한번 읽어들이면 다시 읽을수 없는 값입니다.

이때, 중요한 것은 Scan 함수 실행중, 오류가 발생했다고 하여 입력스트림 값이 비워지는 것이 아니라는 점입니다.

예를들어, 입력스트림에 "apple 3" 이라는 값이 들어있는데, Scan으로 받는 데이터 타입이 정수값일 경우, 맨첫번째 문자 "a"를 읽으면서 바로 오류가 발생되게 됩니다

그러나, 그 이후에 들어있는 "pple 3"은 아직 입력 스트림에 여전히 들어있는 상태입니다.

아래 예제를 통해 자세히 알아봅시다.

package main

import "fmt"

func main() {
	var a, b int

	n, err := fmt.Scan(&a, &b)
	if err != nil {
		fmt.Println(n, err)
	} else {
		fmt.Println(n, a, b)
	}

	var c, d string
	n, err = fmt.Scan(&c, &d)
	if err != nil {
		fmt.Println(n, err)
	} else {
		fmt.Println(n, c, d)
	}
}

apple 3를 입력했을 때, 오류가 발생되지만, 여전히 입력 스트림에는 "pple 3"가 남아있고, 이 값이 c와 d에 들어가게 됩니다.

0 expected integer
2 pple 3

3. 표준 입출력 스트림 비우기

bufio 패키지의 NewReader 객체는 줄바꿈(\n)이 나올 때까지 입력을 받기 때문에,
에러가 발생했을시, stdin.ReadString('\n')를 호출하면 표준 입출력 스트림을 비워지기 때문에 새로 표준 입출력을 입력받을 수 있습니다.

package main

import (
	"bufio"
	"fmt"
	"os"
)

func main() {
	stdin := bufio.NewReader(os.Stdin)
	var a, b int

	n, err := fmt.Scan(&a, &b)
	if err != nil {
		fmt.Println(n, err)
		stdin.ReadString('\n')
	} else {
		fmt.Println(n, a, b)
	}

	n, err = fmt.Scan(&a, &b)
	if err != nil {
		fmt.Println(n, err)
		stdin.ReadString('\n')
	} else {
		fmt.Println(n, a, b)
	}
}
728x90
반응형

'Go' 카테고리의 다른 글

[Go] 07. 배열, 구조체  (1) 2024.01.17
[Go] 06. if문, switch문, for문  (0) 2024.01.16
[Go] 05. 함수, 상수  (0) 2024.01.15
[Go] 03. fmt - 1. 출력  (0) 2024.01.14
[Go] 01. Go 시작하기  (0) 2023.12.28