패키지 fmt
은 C 의 printf
및 scanf
와 유사한 기능으로 포맷된 입출력을 구현하는 기능을 담당한다.
C 에서 파생되었지만 더 간단하다고 한다.
%v 기본적인 값 포맷.
구조체를 출력할 때, %+v 와 같이 사용 시 필드 이름을 추가
%#v 값의 GO 구문으로 표현
%T 값의 타입을 표현
%% 퍼센트(%) 기호, 값을 소비하지 않음
다음과 같은 구조체가 존재한다고 가정한다.
type Test struct {
intVal int
intStr string
}
func main() {
t := &Test{1, "str"}
}
위 구조체 Test
를 출력하면 다음과 같은 결과가 나타난다.
%v : &{1 str} %+v : &{intVal:1 intStr:str} %#v : &main.Test{intVal:1, intStr:"str"} %T : *main.Test %% : %
%t true 또는 false
%b 2 진수
%c 해당 유니코드 포인트로 표시되는 문자
%d 10 진수
%o 8 진수
%O 0o 접두사로 8진수 표현
%q 작은 따옴표의 문자 리터럴을 안전하게 escape 해줌
%x a-f 소문자의 16 진수
%X A-F 대문자의 16 진수
%U 유니코드 포맷: U+1234 -> "U+%04X"
%b 지수가 2의 거듭 제곱인 진수가 없는 과학적 표기법.,
'strconv.FormatFloat' 방식으로 포맷
예) -123456p-78
%e 과학적 표기법, 예) -1.234456e+78
%E 과학적 표기법, 예) -1.234456E+78
%f 소수점이지만 지수가 없음, 예) 123.456
%F %f의 동의어
%g 큰 지수엔 %e, 아니면 %f 가 됨
%G 큰 지수엔 %E, 아니면 %F
%x 16 진법, 예) -0x1.23abcp+20
%X 대문자 16 진수 표기법, 예) -0X1.23ABCP+20
%s 문자열 또는 바이트 조각의 해석되지 않은 바이트들
%q 큰 따옴표 문자열을 안전하게 escape 함
%x 16 진수, 소문자, 바이트 당 두 문자
%X 16 진수, 대문자, 바이트 당 두 문자
%p 0x 로 읽는 16 진법에서의 첫 번째 요소 주소
%p 0x 로 읽는 16 진법
%b, %d, %o, %x 그리고 %X 는 포인터로도 작동함.
값을 정수처럼 정확히 포맷해준다.
다음과 같이 너비 또는 정밀도를 조절할 수 있다.
%f 기본 너비, 기본 정밀도
%9f 너비 9, 기본 정밀도
%.2f 기본 너비, 정밀도 2
%9.2f 너비 9, 정밀도 2
%9.f 너비 9, 정밀도 0
+ 항상 숫자 값에 대한 부호를 출력
%q 에 대한 아스키 전용 출력을 보장
- 왼쪽이 아닌 오른쪽에 공백으로 채움
# 이진에 0b(%#b), 8 진수에 0(%#o), 16 진수는 ox 나 oX(%#x, %#X)
%p 의 경우 0x(%#p)
%q 의 경우, strconv.CanBackquote 가 true 를 반환하면
원시(백틱) 문자열 출력
' ' 생략 부호 위한 공백을 남김 (% d)
16 진수로 문자열 또는 슬라이스를 출력하는
바이트 사이에 공백을 넣음 (% x, % X)
0 공백이 아닌 0 으로 채움. 숫자의 경우 기호 뒤의 패딩으로 이동
var i interface {} = 23
fmt.Printf("%v", i)
위 결과는 26
을 출력한다.
%T
및 %p
로 출력하는 경우를 제외하고 특정 인터페이스를 구현하는 피연신자로 적용된다.
추가적으로 다음과 같은 경우 를 살펴보자.
type X string
func (x X) String() string { return Sprintf("<%s>", x ) }
위 경우는 무한 재귀에 빠질 수 있는 구조이다.
위는 매우 드문 경우이지만 패키지는 보호해주지 않기 때문에 다음과 같이 변환하자.
type X string
func (x X) String() string { return Sprintf("<%s>", string(x)) }
Printf
, Sprintf
, Fprintf
에서 기본 동작은 연속으로 전달된 인수로 형식화 한다.
그러나 동사 바로 앞에 [n]
을 통하여 n 번째임을 명시할 수 있다.
예를 들면
fmt.Sprintf("%[2]d %[1]d", 11, 22)
위 결과는 22 11
로 출력된다.
그리고 명시적 색인는 후속 동사에도 영향을 주어 첫 번째 인수가 반복되도록 색인을 재설정하여 동일한 값을 여러 번 출력할 수 있다.
fmt.Sprintf("%d %d %#[1]x %#x", 16, 17)
위 결과는 16 17 0x10 0x11
로 출력된다.
제공되는 인수의 형식이 잘못되었다면 오류에 대한 설명이 포함된다.
fmt.Printf("%d", "hi")
위는 다음과 같은 결과를 발생한다.
%!d(string=hi)
모든 오류는 %!
로 시작하며 동사가 뒤따르고 그 다음에 괄호로 묶인 설명으로 끝난다.
에러가 출력 루틴에 호출된다면 패닉이 포맷된 메시지가 나타난다.
%!s(PANIC=message)
그리고 패닉이 nil
에 의한 에러가 발생하였다면 출력은 <nil>
이다.
스캔은 형식화된 텍스트를 스캔하여 값을 생성한다.
os.Stdin
에서 읽은 스캔은 지정된 io.Reader
에서 읽는다.
SScan
, SScanf
및 SScanln
은 인수 문자열에서 읽는다.
Scan
, Fscan
, Sscan
은 입력의 개행을 공백으로 처리
Scanln
, Fscanln
, Sscanln
은 줄 바꿈에서 스캔을 중지하고 항목 뒤에 줄 바꿈 또는 EOF
가 있어야 한다.
Scanf
, Fscanf
, Sscanf
는 Printf
와 유사한 형식 문자열에 따라 인수를 구문 분석한다.
여기서 공백은 개행 문자를 제외한 모든 유니 코드 공백 문자를 의미한다.
스캔에서 너비는 입력 텍스트에서 해석되지만 정확한 스캔 구문은 없다. (%5f 는 있지만 %5.2f는 없음)
너비가 제공되면 선행 공백이 잘린 후에 적용되고 동사를 충족시키기 위해
읽을 최대 수를 지정한다.
Sscanf("1234567", "%5s%d", &s, &i)
위는 s 값이 "12345", i 는 67 로 설정하게 된다.
fmt.Sscanf ( "12 34 567", "%5s%d", &s, &i)
위 경우는 s 가 "12", i 는 34가 설정됨.
모든 스캔은 피연산자의 텍스트를 스캔하는데 사용되며, 인수 수가 제공된 인수 수보다 적으면 오류를 반환할 것이다.
func Errorf(format string, a ... interface {}) error
Errorf
는 형식 지정자에 따라 형식을 지정하고 문자열을 오류를 만족시키는 값으로 반환한다.
func Fprint (w io.Writer , a ... interface {}) (n int , err error )
func Fprintf(w io.Writer, format string, a ... interface {}) (n int, err error)
func Fprintln(w io.Writer, a ... interface {}) (n int, err error)
Fprint
는 기본 형식을 w
에 쓴다.
문자열이 아닌 경우엔 피연산자 사이에 공백이 추가된다.
그리고 쓴 바이트 수와 발생한 오류를 반환한다.
Fprintf
는 지정한 형식에 따라 w
에 쓴다.
반환은 동일
Fprintln
은 기본 형식을 w
에 쓰고 피연산자 사이엔 항상 공백이 추가되고 개행 문자가 추가된다.
반환은 동일
func Fscan (r io.Writer , a ... interface {}) (n int , err error )
func Fscanf(r io.Writer, format string, a ... interface {}) (n int, err error)
func Fscanln(r io.Writer, a ... interface {}) (n int, err error)
Fscan
은 r
에서 읽은 텍스트로 연속적인 공백으로 구분된 값을 연속적인 인수에 저장한다.
개행은 공백으로 간주되고 성공적으로 스캔된 항목 수를 반환하고 인수보다 적으면 error 로 이유를 보고한다.
Fsacnf
는 r
에서 읽은 텍스트를 스캔하여 형식에 따라 연속적인 인수에 공백으로 구분하여 연속 값을 저장한다.
반환 동일
Fscanln
은 Fscan
과 유사하지만 개행에서 스캔을 중지하고 항목 뒤에 개행 또는 EOF
가 있어야 한다.
func Print (a ... interface {}) (n int , err error ) func Printf (format string, a ... interface {}) (n int , err error ) func Println (a ... interface {}) (n int , err error ) func Scan (a ... interface {}) (n int , err error ) func Scanf (format string, a ... interface {}) (n int , err error ) func Scanln (a ... interface {}) (n int , err error )
F[Print(f)(ln)][Scan(f)(ln)]
와 형식 동일.
콘솔에 출력을 하거나 읽은 문자열을 스캔한다.
func Sprint(a ...interface{}) string func Sprintf(format string, a ...interface{}) string func Sprintln(a ...interface{}) string func Sscan(str string, a ...interface{}) (n int, err error) func Sscanf(str string, format string, a ...interface{}) (n int, err error) func Sscanln(str string, a ...interface{}) (n int, err error)
동일하게 위 형식 들과 동일.
문자열을 반환하거나 읽은 문자열을 스캔한다.