C 언어에서는 fgetc(stdin)
또는 getc()
함수를 사용하면 사용자가 키를 누르는 즉시 해당 입력을 처리할 수 있다. 이는 엔터키를 입력할 때까지 기다리지 않고 즉각적인 반응을 요구하는 콘솔 애플리케이션이나 게임 개발에서 특히 유용하다.
반면 Golang에서 os.Stdin
을 이용하여 표준 입력을 읽으면 기본적으로 사용자가 엔터키를 누를 때까지 기다리는 라인 버퍼링(Line Buffering) 모드로 동작한다. 이 때문에 키 입력 즉시 이벤트를 처리하기가 어렵다. 하지만 Golang에서는 golang.org/x/term
패키지의 term.MakeRaw()
함수를 사용하여 터미널의 입력 모드를 Raw 모드로 변경할 수 있다. Raw 모드에서는 입력 버퍼링이 비활성화되어 키 입력 즉시 문자를 읽을 수 있다.
다음은 Golang으로 키 입력 즉시 읽는 예제 코드이다.
package main
import (
"bufio"
"fmt"
"log"
"os"
"golang.org/x/term"
)
func main() {
state, err := term.MakeRaw(int(os.Stdin.Fd()))
if err != nil {
log.Fatalf("터미널 모드를 Raw로 전환하는 데 실패했습니다: %v", err)
}
defer term.Restore(int(os.Stdin.Fd()), state)
reader := bufio.NewReader(os.Stdin)
for {
r, _, err := reader.ReadRune()
if err != nil {
log.Printf("입력 읽기 실패: %v", err)
break
}
fmt.Printf("입력된 키: %q\r\n", r)
if r == 'q' {
fmt.Println("프로그램을 종료합니다.")
break
}
}
}
중요한 주의사항으로, term.MakeRaw()
를 호출했다면 반드시 프로그램 종료 시 term.Restore()
를 호출하여 터미널 상태를 복구해야 한다. 이를 지키지 않으면, Linux의 경우 터미널에서 입력이 화면에 표시되지 않는(echo되지 않는) 문제가 발생할 수 있다.
요약
- Golang은 기본적으로 입력 버퍼링을 사용하여 즉각적인 입력 처리에 제한이 있다.
term.MakeRaw()
와term.Restore()
를 통해 입력을 즉각적으로 처리할 수 있다.
- 콘솔 기반 인터페이스(TUI)나 간단한 콘솔 게임 개발에 유용하다.