웹개발일지

Go Scan() 함수의 기본과 활용 본문

Lang/Go

Go Scan() 함수의 기본과 활용

hee_log 2023. 1. 5. 08:43
728x90

 이 글은 터커의 Go 책을 참고하여 Go언어의 Scan()함수에 대한 기본개념과 활용사항을 정리한 글입니다. 

 

 

Scan() 함수 

 Scan()함수는 Go 의 기본 내장패키지인 "fmt"패키지에 내장되어있는 입력 함수이다. 다른 언어들과 다르게 특이한 점은 주소값을 입력받는 것이다. 그 점에서 이 함수가 어떻게 돌아가는 것인지 동작원리를 살펴보았다. 

 

 사용자가 표준 입력장치(키보드)로 입력데이터를 주면 컴퓨터 내부에 표준 입력 스트림이라는 메모리 공간에 임시 저장이 된다. Scan()함수들은 그 표준 입력 스트림에서 값을 읽어 입력값을 처리한다.  

 

var a, b int 
fmt.Scanln(&a, &b)

 

입력 데이터는 연속된 데이터 형태를 갖고있다. 사용자가 "Hello 4"라고 입력하면 표준입력 스트림에 아래 그림과 같이 저장된다. 

 

표준입력 스트림 작동 원리

 이 때 가장 먼저 입력한 데이터부터 읽어오기 때문에 데이터가 거꾸로 저장된다. 먼저 입력된 데이터가 먼저 읽히는 구조를 FIFO (First In First Out)이라고 한다. 표준 입력 스트림이 FIFO 구조를 갖는다. 

 

 Scan() 함수는 표준입력 스트림에서 먼저 한 글자를 읽어온다. 가장 먼저 입력된 글자를 읽어 H가 나온다. 한번 입력된 데이터는 다시 읽어올 수 없기 때문에 표준입력 스트림에서 한 글자를 빼온다고 생각할 수 있다. 

 다만 위 코드에서 입력 받을 값 a와 b를 int타입으로 지정해주었기 때문에 Error를 반환한다. 이런 경우는 입력에 실패하게 되는데 이런경우 표준 입력 스트림을 지워주어야 한다. 

 

 Scanln()함수가 실패한 경우 표준입력 스트림을 비워주는 예제 

package main 

import (
	"bufio"   // io 기능 패키지 
    "fmt"
    "os"      // 표준 입출력 기능 패키지 
 ) 
 
 func main() {
	 stdin := bufio.NewReader(os.Stdin)   // 표준 입력을 읽는 객체 
     var a int 
     var b int 
     
     n, err := fmt.Scanln(&a, &b) 
     
     if err != nil {
     	fmt.Println(err)
        stdin.ReadString('\n') // 표준입력 스트림 지우기; 개행문자가 나올때까지 읽어들이겠단거다
     } else {
        	fmt.Println(n, a, b) 
     }
     n, err = fmt.Scanln(&a, &b)   // 다시 입력받기 
     
     if err != nil {
     	fmt.Println(err) 
     } else {
     	fmt.Println(n, a, b) 
     }
  }

bufio.NewReader(os.Stdin) 

 main 함수 첫번째 줄에서 표준입력객체 stdin을 만들었다. 표준입력 기능들이 담긴 os 패키지의 Stdin객체를 bufio 패키지의 NewReader() 함수에 인자로 넣어 생성했다. 

 ReadString() 

 stdin 객체를 통해 위 함수를 불러와 표준 입력 스트림을 지워주었다. 이전에 잘못된 형식의 입력값을 받아 err가 발생했으므로 스트림을 비워주고 아래서 Scanln()을 통해 다시 값을 받는다. 

 


 Go언어의 기초 문법 중 Scan()함수에 대해 알아보았다. 백준 브론즈5 1000번 문제를 풀다가 Scan()함수의 사용법을 잊어버려 제대로 찾아보고 복습하게되었다. Scan()함수가 입력값으로 주소값을 받고 입력받은 개수와 에러를 반환한다는 것을 알게되었다. 또한 기초 예제를 통해 에러처리 구문을 복습할 수 있었다.