개발/c++

C/C++ printf format specifier 정리

하또또🍊 2022. 7. 27. 00:44

printf 류의 log 함수에 사용되는 specifier 를 정리 하였습니다. 

 

 

포맷지정자(format specifier)

아주 기본적이고 간단한 내용이지만, 자주쓰는 %d, %s 이외에는 써야할 때 마다 매번 다시 찾아보게 되네요.

우선 각 대상에 따른 specifier 는 아래와 같습니다.

대상 Specifier 메모
부호있는 10진 정수형 d i도 동일함
부호없는 10진 정수형 u  
부호 없는 8진 정수형 o  
부호 없는 16진 정수형 x X로 사용시 대문자로 출력됨
고정 소숫점 실수형 f F로 사용시 대문자로 출력됨
부동 소숫점 실수형 (e-) e E로 사용시 대문자로 출력됨
값에 따라 %e 혹은 %f g  
값에 따라 %E 혹은 %F G  
16진수 부동소수점 a A로 사용시 대문자로 출력됨
문자 형태 c  
문자열 형태 s  
Pointer 주소 p  
    printf ("  %%d(-100)->[%d]\n", -100);
    printf ("  %%i(-100)->[%i]\n", -100);
    printf ("  %%u(-100)->[%u]\n", -100);
    printf ("   %%o(100)->[%o]\n", 100);
    printf ("   %%x(100)->[%x]\n", 100);
    printf ("%%f(3.1416)->[%f]\n", 3.1416);
    printf ("%%e(3.1416)->[%e]\n", 3.1416);
    printf ("%%g(3.1416)->[%g]\n", 3.1416);
    printf ("   %%c('a')->[%c]\n", 'a');
    printf (" %%s('abc')->[%s]\n", "abc");
  %d(-100)->[-100]
  %i(-100)->[-100]
  %u(-100)->[4294967196]
   %o(100)->[144]
   %x(100)->[64]
%f(3.1416)->[3.141600]
%e(3.1416)->[3.141600e+00]
%g(3.1416)->[3.1416]
   %c('a')->[a]
 %s('abc')->[abc]

 

sub-specifier

위의 지정자만 사용하여도 기본적인 출력값의 형태를 지정할수 있지만, 

optional 하게 flag, width, priecision, length 라는 sub-specifier를 사용하여 좀 더 세밀하게 출력형태를 조절 할 수도있습니다. 

%[flags][width][.precision][length]specifier

flags

flags description
- 주어진 width 내에서 왼쪽맞춤
+ 기호부호 출력(+/-) 설정하지 않으면 기본적으로 -만 출력됨
 (space) 부호가 없는 경우, 공백이 값 앞에 출력됨
# o 나 x 와 함께 사용하면 0 0x 0X와같은 값이 앞에 출력됨
0 width가 잇는경우 공백대신 0으로 숫자왼쪽을 채움

width

width description
(number) 출력할 최소 문자 수. 출력될 값의 길이가 이 수 보다 짧은경우, 공백으로 채워짐
* 인자로 전달된 정수값을 width로 사용
    //- or +
    printf ("  %%10d(100)->[%10d]\n", 100);
    printf (" %%-10d(100)->[%-10d]\n", 100);
    printf (" %%+10d(100)->[%+10d]\n", 100);
    
    //space
    printf ("    %%d(100)->[%d]\n", 100);
    printf ("   %% d(100)->[% d]\n", 100);
    
    //#
    printf ("    %%x(100)->[%x]\n", 100);
    printf ("   %%#x(100)->[%#x]\n", 100);
    
    //0
    printf ("  %%10d(100)->[%10d]\n", 100);
    printf (" %%010d(100)->[%010d]\n", 100);
    
    //width*
    printf ("%%*d(10,100)->[%*d]\n", 10, 100);
    printf (" %%*d(5,100)->[%*d]\n", 5, 100);
  %10d(100)->[       100]
 %-10d(100)->[100       ]
 %+10d(100)->[      +100]
    %d(100)->[100]
   % d(100)->[ 100]
    %x(100)->[64]
   %#x(100)->[0x64]
  %10d(100)->[       100]
 %010d(100)->[0000000100]
%*d(10,100)->[       100]
 %*d(5,100)->[  100]

length 값은 부호 및 모든 padding을 포함하여 최종적으로 출력되는 길이, flags는 출력 할 값을 꾸며주는 옵션으로 보면 되겠습니다. 

 

precision

.precision description
.number (d, i, o, u, x) 정수형의 경우, 출력할 최소개수를 지정. 인자의 길이가 그보다 짧을 경우, 0으로 채워짐
(a, e, f) 실수형의 경우, 소숫점 뒤에 출력될 숫자의 개수를 지정.(default는  6)
(g) 의 경우, 출력할 최대 유효자리수
(s) 의 경우, 출력할 문자열의 최대 자리수(default로는 null 문자열이 나타날때까지)
.* 인자로 전달된 정수값을 precision로 사용
    printf ("      %%.4d(100)->[%.4d]\n", 100);
    printf ("    %%.4f(3.141)->[%.4f]\n", 3.141);
    printf ("   %%.4g(3.1415)->[%.4g]\n", 3.1415);
    printf ("%%.4s('abcdefg')->[%.4s]\n", "abcdefg");
    printf ("      %%.*d(100)->[%.*d]\n", 5, 100);
      %.4d(100)->[0100]
    %.4f(3.141)->[3.1410]
   %.4g(3.1415)->[3.142]
%.4s('abcdefg')->[abcd]
      %.*d(100)->[00100]

 

length

출력할 data type의 길이를 변경

length description
hh (d, i, u, o, x) 정수형을 short char, unsigned char로
h (d, i, u, o, x) 정수형을 short int, unsigned short int로
l (d, i, u, o, x) 정수형을 long int, unsigned long int로, (c)를 wint_t로, (s)를 wchar_t* 로
ll (d, i, u, o, x) 정수형을 long long int, unsigned long long int로
j (d, i, u, o, x) 정수형을 intmax_t, uintmax_t로
z (d, i, u, o, x) 정수형을 size_t로
t (d, i, u, o, x) 정수형을 ptrdiff_t로
L (f, e, g, a) 실수형을 long double로
std::vector<int8_t> testVector = {1, 2, 3};
uint64_t testint64 = 12341234523;

//warning: format '%d' expects argument of type 'int', but argument 2 has type 'std::vector<singed char>::size_type {aka long unsigned int}'
printf ("%%d(testVector.size())->[%d]\n", testVector.size());

//no warning
printf ("%%zd(testVector.size())->[%zd]\n", testVector.size());

//warning: format '%d' expects argument of type 'int', but argument 2 has type 'uint64_t {aka long unsigned int}'
printf ("%%d(testint64)->[%d]\n", testint64);

//no warning
printf ("%%ld(testint64)->[%ld]\n", testint64);

vector size출력하는 경우, 위의 warning이 발생하여 casting으로 처리를 해주는 경우가 많은데, 

%zd를 사용하여 간단히 warning을 제거할 수 있었습니다. 

 

 

 

참고 페이지:

https://cplusplus.com/reference/cstdio/printf/