본문 바로가기
CS

[Go] Go에서의 표준 입출력(with fmt)

by cuda 2022. 9. 21.

표준 입출력

fmt 패키지

Go의 기본 패키지인 fmt는 표준 입출력 기능을 제공한다.

출력

fmt 패키지가 제공하는 3가지의 표준 출력 함수는 다음과 같다.

  • Print() : 함수 입력값들을 출력

  • Println() : 함수 입력값들을 출력하고 개행

  • Printf() : 서식(format)에 맞도록 입력값들 출력 (자동 개행 미지원)

    Printf(문자열, 인수, 인수) //Printf() 형식

    서식 문자Printf()와 함께 사용하는 서식 문자는 다음과 같다.

서식 문자 효과
%v 데이터 타입에 맞추어 기본 형태로 출력
%T 데이터 타입을 출력
%t boolean 타입 출력
%d 10진수 정수로 출력(정수 타입만 가능)
%b 2진수로 출력
%c 유니코드 문자 출력(정수 타입만 가능)
%o 8진수로 출력
%O 8진수로 출력, 단, 앞에 Oo를 붙여서 출력
%x 16진수로 출력(10 이상의 값을 a-f와 같은 소문자로 출력)
%X 16진수로 출력(10 이상의 값을 A-F와 같은 대문자로 출력)
%e, %E 실수를 지수 형태로 출력(실수 타입만 가능)
%f, %F 실수를 출력(실수 타입만 가능)
%g, %G 값이 큰 실수는 지수 형태로 출력하고, 값이 작은 실수는 실수 그대로 출력
%s 문자열을 출력
%q escape sequence를 동작하지 않고 그대로 문자열 출력
%p 메모리 주솟값 출력

최소 출력 너비 지정

최소 출력 너비 지정의 경우, 타 언어들과 크게 다른 점은 없다.

  • 최소 출력 너비 지정 : 서식 문자에서 %와 타입을 나타내는 알파벳 사이에 숫자를 넣어 너비 지정
    Ex) %4d, %3f
    fmt.Printf("%4d , %4d\n", a, b) // 최소 출력 너비 지정
  • 공란 채우기 : 너비를 지정하는 숫자 앞에 0을 붙여 빈 자리를 0으로 채울 수 있음.
    Ex) %04d, %4f
    fmt.Printf("%04d , %04d\n", a, b) // 공란 채우기
  • 왼쪽 정렬 : - 를 추가하여 출력 기준을 오른쪽에서 왼쪽으로 바꿀 수 있다.
    fmt.Printf("%-4d , %-4d\n", a, b) // 왼쪽 정렬 
    fmt.Printf("%-04d , %-04d\n", a, b) // 이 경우에는 공란 채우기 적용 X, 왼쪽 정렬만 적용됨

이 때, 만약 값이 최소 너비보다 길면 최소 너비는 무시된다

  fmt.Printf("%6d\n", c) // 값이 최소 너비보다 길면 최소 너비 무시됨

실수의 소수점 자릿수

실수의 소숫점 자릿수 설정의 경우에도, 타 언어들과 크게 다르지 않다.
그러나, %f와 %g의 소수점 자릿수 설정에는 약간의 차이가 있다.

  • %f : %(최소 너비).(소수점 자릿수)f
    Ex) %6.2f : 최소 너비 6칸, 소수점 이하 값 2
    fmt.Printf("%8.2f\n", a) // 소수점 숫자 2개에 최소 너비 8칸 
    fmt.Printf("%08.2f\n", a) // 공란 채우기 적용
  • 아무런 설정을 하지 않은 %f은 기본적으로 소숫점 이하 값을 6개까지 출력한다.
    fmt.Printf("%f\n", b)
  • %g : %(최소 너비).(정수부+소숫점 자릿수)g
    만약, .다음의 (정수부+소숫점 자릿수)를 넘어가게 된다면 지수 표현으로 출력된다
    fmt.Printf("%8.2g\n", a) // 최소 너비 8, 총 숫자는 2 
    fmt.Printf("%08.2g\n", a) // 공란 채우기 적용

입력

fmt 패키지가 제공하는 3가지의 표준 입력 함수는 다음과 같다.

  • Scan() : 표준 입력에서 값을 입력받음
    Scan() 함수의 경우, 값을 채워넣을 변수들의 메모리 주소를 인수로 받는다.
    또한, 반환값으로 입력 성공한 갯수와 입력 실패 시 에러(입력 성공 시 nil)를 반환한다.
    n, err := fmt.Scan(&a, &b) 
    // Scan()함수의 반환값 : 입력 성공한 갯수와 입력 실패 시 에러
  • Scanf() : 표준 입력에서 서식 형태로 값을 입력받음
  • Scanln() : 표준 입력에서 한 줄을 읽어서 값을 입력받음
    Scanln() 함수의 경우에도 반환값으로 입력 성공한 갯수와 입력 실패 시 에러(입력 성공 시 nil)를 반환한다.
    다만, Scanln()은 마지막 입력값 이후 반드시 enter로 입력 종료해야 함.
    n, err := fmt.Scanln(&a, &b) 
    // Scanln()함수의 반환값 : 입력 성공한 갯수와 입력 실패 시 에러

Scan()함수의 동작 원리

PC에서 표준 입력 장치(키보드)로 입력하게 되면, 해당 데이터는 표준 입력 스트림(standard input stream)에 임시 저장된다
이후 Scan()함수(혹은 Scanf(), Scanln())는 표준 입력 스트림에서 값을 읽어오는 원리이다.

표준 입력 스트림에서 Scan()으로 읽힌 값은 다시 읽힐 수 없으며,
만약 읽는 도중에 중단되면 나머지 값들은 여전히 표준 입력 스트림에 남아있게 된다.
이러한 상태에서 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') // 줄바꿈 \n이 나올때까지 계속 읽기 (표준 입력 스트링 지우기)
    } else {
        fmt.Println(n, a, b)
    }
    n, err = fmt.Scanln(&a, &b) // 여기서는 초기화가 아니라 선언 대입문 :=를 사용하지 않음
    if err != nil {
        fmt.Println(err)
        stdin.ReadString('\n') // 줄바꿈 \n이 나올때까지 계속 읽기 (표준 입력 스트링 지우기)
    } else {
        fmt.Println(n, a, b)
    }
}

'CS' 카테고리의 다른 글

[JavaScript] npm 살펴보기  (0) 2022.09.28
[JavaScript] nvm 살펴보기  (0) 2022.09.28
[Go] Go에서의 변수  (1) 2022.09.21
[자료구조] 힙(Heap)이란?  (0) 2022.08.21
[자료구조] 해시 테이블(Hash Table)이란?  (0) 2022.08.21

댓글