OS가 제공하는 표준 입출력 스트림을(standard input/output) 사용하여 입력과 출력을 간편하게 처리할 수 있다.
Go에서는 Go 언어 기본 패키지는 fmt에서 표준 입출력 기능을 제공한다.
- fmt패키지는 3가지 표준 출력용 함수를 제공한다.
Print() 함수 입력값들을 출력한다. PrintIn() 함수 입력값들을 출력 및 개행한다. Printf() 서식(format)에 맞도록 입력값들을 출력한다.
서식문자
Printf() 함수는 다음과 같은 형식으로 사용된다.
Printf(서식 지정자, 인수1, 인수2)
- 서식 지정자 설명
구분 설명 %v 데이터 타입에 맞춰서 기본 형태로 출력한다. %T 데이터 타입 출력한다. %t 불리언을 true/false로 출력 %d 10진수 정숫값으로 출력 (only 정수타입) %b 2진수로 출력 %c 유니코드 문자를 출력 %o 8진수로 출력 %O 앞에 8진수임을 표시하는 0o를 붙여서 8진수로 값을 출력 %x 16진수로 값을 출력 (10 이상 값을 a-f 소문자로 표시) %X 16진수로 값을 출력 (10 이상 값을 a-f 대문자로 표시) %e %E 지수 형태로 실숫값을 출력 (실수 타입만 가능) %f %F 지수 형태가 아닌 실숫값 그대로 출력 (실수 타입만 가능) %g %G 값이 큰 실숫값은 지수 형태(%e)로 출력 %s 문자열을 출력 %q 특수문자 기능을 동작하지 않고 그대로 출력 %p 메모리 주솟값을 출력
최소 출력 너비 지정
서식 문자를 이용하여 다음과 같은 작업을 할 수 있다.
- 최소 출력 너비 지정
- 공란 채우기
- 왼쪽 정렬하기
1️⃣ 최소 출력 너비 지정
package main
import "fmt"
func main() {
var a = 123
var b = 456
fmt.Printf("%5d, %5d\\n", a, b)
}
> 123, 456
%와 타입을 나타내는 문자 사이에 숫자를 넣어서 너비를 지정할 수 있다.
- %5d는 최소 5칸을 사용하여 정숫값을 출력한다.
2️⃣ 공란 채우기
package main
import "fmt"
func main() {
var a = 123
var b = 456
fmt.Printf("%05d, %05d\\n", a, b)
}
>00123, 00456
너비 앞에 0을 붙이면 빈자리를 0으로 채운다.
- 최소 5칸을 사용하고 공란에 0을 채운다.
3️⃣ 왼쪽 정렬하기
package main
import "fmt"
func main() {
var a = 123
var b = 456
fmt.Printf("%-5d, %-05d\\n", a, b)
}
>123 , 456
마이너스를 붙이면 왼쪽을 기준선 삼아 출력한다.
- 일정 간격으로 숫자들을 출력할 수 있다.
실수 소수점 이하 자릿수
실숫값에는 소수점 이하 자릿수도 지정할 수 있다.
- %f
- 실수를 출력한다.
- ex) %5.2f : 최소 너비 5칸에 소수점 이하 값 2개를 출력한다.
- %g
- 실수를 정수부와 소수점 이하 숫자를 포함하여 출력 숫자를 제한한다.
- ex) %5.3g : 최소 너비 5칸에 소수점 이하 포함하여 총 숫자 3개로 표현한다.
특수문자
\n | 줄바꿈 한다. |
\t | 탭을 삽입한다. |
\\ | \ 자체를 출력한다. |
\” | “를 출력한다. 큰따옴표로 묶인 문자열 내부에 따옴표를 넣을 때 사용한다. |
표준입력
표준 입출력 장치에서 데이터를 얻어온다.
- 일반적으로는 키보드가 표준 입력 장치이다.
- 아래의 함수는 변수들의 메모리 주소(&)를 인수로 넘겨줘야 한다.
Scan() | 값을 채워넣을 변수들의 메모리 주소를 인수로 받는다. |
Scanf() | 표준 입력에서 서식형태로 값을 입력받는다. |
Scanln() | 표준 입력에서 한 줄을 읽어서 인수로 들어온 변수 메모리 주소에 값을 채워준다. |
예제
Scan()
Scan()함수는 값을 채워넣을 변수들의 메모리 주소를 인수로 받는다.
- 한 번에 여러 값을 입력받을 떄는 변수 사이를 공란을 두어 구분한다.
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)
}
}
- Scan() 함수의 입력으로 쓸 때에는 변수 앞에 &를 붙여서 변수의 메모리 주소를 입력으로 넘겨야한다.
- err가 nil이 아니면 에러이다.
Scanf()
Scanf()는 서식에 맞춘 입력을 받는다.
💡 서식에 맞춰서 입력하기가 힘들기 때문에 Scan()이나 Scanln() 함수 사용을 추천한다.
//ch5/ex5.6/ex5.6.go
package main
import "fmt"
func main() {
var a int
var b int
n, err := fmt.Scanf("%d %d\\n", &a, &b) // ❶ 입력 두 개 받기
if err != nil {
fmt.Println(n, err)
} else {
fmt.Println(n, a, b)
}
}
Scanln()
한 줄을 입력받아서 인수로 들어온 변수 메모리 주소에 값을 채워준다.
- Scan()과 다른점은 마지막 입력값 이후 반드시 enter 키로 입력을 종료해야 한다.
//ch5/ex5.7/ex5.7.go
package main
import "fmt"
func main() {
var a int
var b int
n, err := fmt.Scanln(&a, &b) // ❶ 값을 입력받습니다.
if err != nil { // 에러 발생 시
fmt.Println(err) // 에러를 출력합니다.
} else {
fmt.Println(n, a, b)
}
}
Scan() 함수의 동작원리
만약, int 타입 입력을 받고자 사용자가 “Hello 4” 를 입력한다면 가장 먼저 입력된 데이터부터 읽어오기 때문에(FIFO 방식) 데이터가 거꾸로 저장된다.
- Scan()함수는 가장 먼저 입력된 글자가 읽히기 떄문에 H를 읽어온다.
- 한 번 읽은 데이터는 다시 읽어올 수 없다.
- 그런 다음 읽어온 글자가 원하는 타입인지 판단한다.
- 위 경우에는 int 타입에 string이라 Error를 반환한다.
- 그 후에 다시 Scanln()이 호출됐을 때 새로운 입력을 받는게 아니라 기존에 남아있는 표준 입력 스트림에서 다시 값을 가져오기 때문에 ‘e’를 가져오고 Error를 반환한다.
따라서 여러번 Scan() 함수를 호출할 때 위와 같은 문제에서 벗어나려면 입력에 실패한 경우 표준 입력 스트림을 지워줘야 한다.
package main
import (
"bufio"
"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
- 표준 입력 스트림에서 한 줄을 읽어오는 데 bufio, os 등의 패키지를 사용한다.
- bufio는 입력 스트림으로부터 한 줄을 읽는 Reader 객체를 제공한다.
- stdin := bufio.NewReader(os.Stdin)
- NewReader() 함수는 인수로 입력되는 입력 스트림을 가지고 Reader 객체를 생성해준다.
- 여기서는 표준 입력 스트림을 나타내는 os.Stdin을 사용하여 Reader 객체를 만든다.
- stdin.ReadString('\\n')
- 줄바꿈 문자가 나올 때 까지 읽는다.
- 이렇게 하면 표준 입력 스트림이 비워진다.
'Programming > Go' 카테고리의 다른 글
[Golang] 함수 (Function) (1) | 2022.10.29 |
---|---|
[Golang] 연산자 (Operator) (0) | 2022.10.29 |
[Golang] 변수 (0) | 2022.10.22 |
[Golang] 코드 실행과정 (0) | 2022.10.17 |
[Golang] Go는 어떤 언어? (1) | 2022.09.23 |