[Go 언어] 25. 콘솔 입력 함수 Scanln, Scan, Scanf 사용하기

안녕하세요. 언제나 휴일, 언휴예요.

이번 게시글에서는 콘솔에서 입력받을 때 사용하는 Scanln, Scan, 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):

Scanln 함수는 공백으로 구분하여 입력받는 함수이며 Scan함수는 공백과 개행으로 구분하여 입력받는 함수입니다. Scanf는 포멧 지정자를 이용하여 개발자가 원하는 형태로 출력하는 함수죠.

새 프로젝트를 생성하여 Scanln 함수를 사용해 보아요.

[그림] LiteIDE에서 새 프로젝트 생성 및 소스 파일 추가
// Example Scanln
package main

import "fmt"

func main() {
    var name string
    fmt.Print("이름:")
    fmt.Scanln(&name)
    var num int
    fmt.Print("번호:")
    fmt.Scanln(&num)
    var addr string
    fmt.Print("주소:")
    fmt.Scanln(&addr)
    fmt.Println("이름은 ", name, " 번호는 ", num)
    fmt.Println("주소는 ", addr)
}

Scanln 함수로 콘솔에서 입력한 값을 받을 때는 언제나 주소 앞에 참조 연산자 &를 붙여서 사용해야 합니다. 주의할 점은 공백을 기준으로 변환한다는 것이예요.

    var addr string
    fmt.Print("주소:")
    fmt.Scanln(&addr)

이름에 “abc”, 번호에 “12”, 주소에 “Seoul” 라고 입력하였을 때 출력 결과는 다음과 같아요.

이름:abc (abc는 입력)
번호:12  (12는 입력)
주소:Seoul (Seoul은 입력)
이름은  abc  번호는  12
주소는  Seoul
[그림] Scanln 실행 결과

다음처럼 Scanln 함수에 참조 연산자와 변수의 쌍을 여러 개 두어 한꺼번에 입력받을 수도 있어요.

// Example Scanln2
package main

import "fmt"

func main() {
	var name, addr string
	var num int
	fmt.Println("이름 번호 주소")
	fmt.Scanln(&name, &num, &addr)
	fmt.Println("이름은 ", name, " 번호는 ", num)
	fmt.Println("주소는 ", addr)
}
[그림] Scanln 실행 결과2

그리고 Scanln 함수는 입력한 값을 변환하지 못하였을 때 변환 성공한 개수를 반환합니다.

Scanln 함수는 반환  값이 int 형식 값과 error 형식 값을 전달하며 반환 값을 받을 때 다음처럼 표현합니다.

re, _ = fmt.Scanln(&name, &num, &addr)

다음은 Scanln 함수의 반환 값을 확인하는 코드예요.

// Example Scanln3
package main

import "fmt"

func main() {
	var name, addr string
	var num int
	fmt.Println("이름 번호 주소")
	var re int
	re, _ = fmt.Scanln(&name, &num, &addr)
	fmt.Println("이름은 ", name, " 번호는 ", num)
	fmt.Println("주소는 ", addr)
	fmt.Println(re)
}
[그림] Scanln 실행 결과3

위 실행 결과를 보면 번호를 입력하는 부분에 “ab”를 입력했어요. Scanln 함수에서는 이름은 변환 성공하였지만 번호를 변환하지 못하여 바로 함수를 종료합니다. 이 때 반환한 int 형식 값은 변환 성공한 1인 것을 알 수 있어요.

Scan 함수와 Scanln 함수의 차이점은 Scan 함수는 공백이나 개행을 기준으로 변환을 하지만 Scanln은 공백만을 기준으로 변환하며 개행을 만나면 입력 완료로 인지하여 변환 후 결과를 반환합니다.

// Example Scan
package main

import "fmt"

func main() {
	var name, addr string
	var num int
	fmt.Println("이름 번호 주소")
	var re int
	re, _ = fmt.Scan(&name, &num, &addr)
	fmt.Println("이름은 ", name, " 번호는 ", num)
	fmt.Println("주소는 ", addr)
	fmt.Println(re)
}
[그림] Scanln 실행 결과4
[그림] Scan 실행 결과

위의 두 개의 실행 결과를 보면 Scanln 함수를 이용하여 이름, 번호, 주소를 입력받을 때 “a개행”을 입력하였을 때 이름은 변환하지만 입력 종료 처리하여 나머지는 입력을 받지 않음을 알 수 있습니다. 하지만 Scan 함수를 사용한 예를 보면 개행을 입력한 후에도 다른 변수의 값을 입력받는 것이 가능함을 알 수 있어요.

Scanf 함수는 포멧을 지정하여 콘솔에서 입력받는 함수입니다.

다음은 IPv4 주소를 “XXX.XXX.XXX.XXX” 형태로 입력하면 네 개의 정수형 변수에 변환받는 예제 코드입니다.

// Example Scanf
package main

import "fmt"

func main() {
	var n1, n2, n3, n4 int
	fmt.Println("IPv4 주소")
	fmt.Scanf("%d.%d.%d.%d", &n1, &n2, &n3, &n4)
	fmt.Printf("입력한 IPv4주소는 %d.%d.%d.%d\n", n1, n2, n3, n4)
}
[그림] Scanf 실행 결과

위의 실행 결과를 보면 알 수 있듯이 Scanf 함수에서는 포멧 지정자 외에 포멧 문자열에 표현한 내용도 사용자가 입력할 때 맞춰서 입력하는 것을 요구하면 해당 문자는 스킵합니다. 위에서는 정수 사이에 점(.)을 스킵하고 있습니다.

이상으로 콘솔에서 입력받는 세 개의 함수를 알아 보았어요. 다음 주제부터 제어문에 대해 다룰 거예요.

모두 행복한 하루~