[GO] #3-1. 패키지 탐방 (fmt)

Study·2021년 5월 19일
0

고랭

목록 보기
8/18
post-thumbnail

fmt

패키지 fmt 은 C 의 printfscanf 와 유사한 기능으로 포맷된 입출력을 구현하는 기능을 담당한다.

C 에서 파생되었지만 더 간단하다고 한다.

Printing

일반

%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
%%  :	 %

Boolean

%t	true 또는 false

Integer

%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"

Float

%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

String 과 Byte 조각

%s	문자열 또는 바이트 조각의 해석되지 않은 바이트들
%q	큰 따옴표 문자열을 안전하게 escape 함
%x	16 진수, 소문자, 바이트 당 두 문자
%X	16 진수, 대문자, 바이트 당 두 문자

Slice

%p	0x 로 읽는 16 진법에서의 첫 번째 요소 주소

Pointer

%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> 이다.

Scanning

스캔은 형식화된 텍스트를 스캔하여 값을 생성한다.
os.Stdin 에서 읽은 스캔은 지정된 io.Reader 에서 읽는다.

SScan, SScanfSScanln 은 인수 문자열에서 읽는다.

Scan, Fscan, Sscan 은 입력의 개행을 공백으로 처리

Scanln, Fscanln, Sscanln 은 줄 바꿈에서 스캔을 중지하고 항목 뒤에 줄 바꿈 또는 EOF 가 있어야 한다.

Scanf, Fscanf, SscanfPrintf 와 유사한 형식 문자열에 따라 인수를 구문 분석한다.
여기서 공백은 개행 문자를 제외한 모든 유니 코드 공백 문자를 의미한다.

스캔에서 너비는 입력 텍스트에서 해석되지만 정확한 스캔 구문은 없다. (%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가 설정됨.

모든 스캔은 피연산자의 텍스트를 스캔하는데 사용되며, 인수 수가 제공된 인수 수보다 적으면 오류를 반환할 것이다.

fmt 함수

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)

Fscanr 에서 읽은 텍스트로 연속적인 공백으로 구분된 값을 연속적인 인수에 저장한다.
개행은 공백으로 간주되고 성공적으로 스캔된 항목 수를 반환하고 인수보다 적으면 error 로 이유를 보고한다.

Fsacnfr 에서 읽은 텍스트를 스캔하여 형식에 따라 연속적인 인수에 공백으로 구분하여 연속 값을 저장한다.
반환 동일

FscanlnFscan 과 유사하지만 개행에서 스캔을 중지하고 항목 뒤에 개행 또는 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)

동일하게 위 형식 들과 동일.
문자열을 반환하거나 읽은 문자열을 스캔한다.

profile
Study

0개의 댓글