printf(3)

#include <stdio.h>

int printf(const char *format, ...);

printf(3)함수는 화면에 format에 맞는 형태로 화면에 출력하는 동적 파라미터(갯수, 타입이 정해지지 않은)함수입니다. 이 함수는 동적 파라미터 함수이므로 format 문자열을 parsing하여 format 뒤에 따라오는 변수들의 갯수와 type을 짐작하여 화면에 출력하게 됩니다. 따라서 format의 형식을 잘 이해하는 것이 이 함수를 사용하는 데, 관건입니다.

 

 

파라미터

format
    - 데이터를 출력할 형식을 지정하는 문자열
    - format에는 그냥 출력할 문자열과 뒤에 따른 변수(...)의 데이터를 치환하기 위한 형식을 저장합니다. 
...
    - format에 나열된 순서에 맞는 데이터

 

RETURN

0 이상
    - 출력된 바이트 수

 


format의 구성

% flag_character field_width .pricision length_modifier conversion_specifier 

  - %  : 한 개의 데이터 format 시작
  - flag_character : 데이터의 정렬 또는 빈자리 채우는 방식에 대한 표현 (optional)
  - field_width : 전체 폭 설정 (optional)
  - .pricision  : 정밀도 폭 설정 또는 실수의 소숫점 자리수 설정 (optional)
  - length_modifier : 동적 파라미터의 데이터 type
  

한 개의 데이터 출력 format은 %로 시작하여 flag_character  field_width .pricision length_modifier conversion_specifier 순서 대로 표시해야 합니다.  flag_character  field_width .pricision length_modifier는 optional로 반드시 사용되는 것은 아닙니다.

 

 

%

1개의 동적 파라미터 변수에 대한 formatting을 시작하는 표시 

 

flag_character (optional)

# 
    - 16진수 표기 0x 또는 0X 표시 - conversion_specifier(x, X)인 경우만
    
0 
    - conversion_specifier가 숫자형인 경우에 좌측에 0으로 채움
    
- 
    - 데이터를 좌정렬
    
+ 
    - conversion_specifier가 숫자형인 경우에 +값의 경우 +를 붙임
    
' ' 
    - 데이터가 모자라는 경우는 space로 채움 (' '가 없어도 space로 채우므로 잘 사용 안함

flag_character는 optional로 0개 또는 여러개의 조합으로 사용 가능합니다.

 

 

field_width (optional)

출력할 전체 폭 설정 
- 최소폭이므로 데이터의 길이가 이 값을 초과하면 데이터가 잘리는 것이 아니라 더 길게 표시됩니다.

숫자 : 고정 폭으로 지정됨. 
  예)
    printf("[%10d]\n", 200);
  결과>
    [200       ]
    
*  :  폭을 파라미터로 받아서 동적으로 정함
  예)
    int width = 6;
    printf("[%*d]\n", width, 200);  
  결과>
    [200   ]

 

.precision (optional)

.숫자
   - 고정 길이 지정
.*  
   - 변수로 지정(...파라미터에 길이 정보가 추가되어야 합니다.)

conversion_specifier가 실수형 변수이면 
   - 소수점 이하 몇 자리까지 표현할 것인지를 설정합니다.

conversion_specifier가 실수형 이외의 변수이면
   - 최대폭을 지정합니다. 최대폭보다 긴 데이터는 앞에서부터 폭까지만 출력되고 잘립니다.

 

length_modifier (optional)

conversion_specifier의 데이터 type의 크기를 지정합니다.

hh
    - 정수형의 데이터를 signed char 또는 unsigned char로 데이터 크기를 조정입니다.
    ex)
       printf("[%hhd]\n", 1000);
       결과:
       [-24]
       
       printf("[%hhu]\n", 1000);
       결과:
       [232]

h
    - 정수형의 데이터를 signed short int 또는 unsigned short int로 데이터 크기를 조정합니다.
    
l
    - 정수형의 데이터를 long int 또는 unsigned long으로 데이터 크기를 조정합니다.

ll
    - 정수형의 데이터를 long long int 또는 unsigned long long int로 데이터 크기를 조정합니다.

q
    - ll과 같음

L
    - 실수형 데이터를 long double로 데이터 크기를 조정합니다.
      (a, A, e, E, f, F, g, G)

 

conversion_specifier

동적 파라미터(...) 변수의 데이터 type

d 또는 i 
    - signed int 표현

o
    - 8진수 unsigned int 표현
    
u
    - 10진수 unsigned int 표현

x, X
    - 16진수 unsigned int 표현 
    - flag_character #를 사용하는 경우 x는 0x로, X는 0X 표시함

e, E
    - 실수를 표시할 때에 [-]d.dddE[±]dd 형식으로 표시함
      ex).
          3.12e-5 , 3.12E-5 
          -2.74e+6 , -2.74E+6
          
f, F
    - 실수를 표시할 때에  [-]ddd.ddd 형식으로 표시함
       ex).
          12567.45
          
g, G
    - 실수를 f, F로 표시할 수 있는 범위이면 f, F 표시법을 그렇지 않으면 e, E 표시법을 사용함

 a, A
    - 실수를 16진 표기법으로 표시함 ([-]0xh.hhhhp±)
    
c
    - char 를 표시함

s 
    - const char * 를 표시함

p
    - pointer변수의 번지를 출력함
      %#x 또는 %#lx 와 같음

m
    - printf("%m")은 printf("%s", strerror(errno))와 같음.
    - 동적 파라미터가 없이 표시됨

%
    - %자체를 표시함

 


활용 예제

 

sample1). flag_character +와 -의 의미

#include <stdio.h>

int main(int argc, char **argv)
{
    char name[]     = "홍길동";
    int  age        = 25;
    int  wgt        = 80;
    int  pwgt       = 77;
    int  inc        = wgt - pgt;

    printf("[%-20s] [%4d] [%4d] [%4d] [%+4d]\n", name, age, wgt, pwgt, inc);
    
    return 0;
}

결과>
[홍길동           ] [  25] [  80] [  77] [  +3]

위의 내용에서 "%-20s"는 -로 인하여 좌측 정렬이 되고 -가 없는 경우 우측 정렬이 됩니다. 또한 마지막의 inc값 출력에서 "%+4d"는 +값이면 +기호를 표시합니다. 만약, inc를 "%+-4d"라고 했다면 [+3  ]로 표현이 됩니다. 즉, +에 의해서 숫자의 부호 표시가 되고 -에 의해서 좌정렬이 됩니다.

 


 

sample2). 문자열 폭 지정

#include <stdio.h>

int main(int argc, char **argv)
{
    char str1[]     = "123456789012345678901234567890";


    printf("[%10s]\n", str1);
    printf("[%.10s]\n", str1);
    
    return 0;
}

결과>>
[123456789012345678901234567890] 
[1234567890] 

field_with(전체폭)값은 최소 유지폭입니다. 따라서 printf("[%10s]\n", str1);처럼 출력을 하면, str1이 30바이트 이므로 폭이 30자리로 늘어납니다. printf("[%.10s]\n", str1);처럼 .precision으로 표시하면 이는 최대 폭으로 인식됩니다. 그래서 실제 데이터는 30바이트인 데, 잘려서 폭이 10으로 표시됩니다.

 


Sample3. 동적으로 폭을 지정하기

#include <stdio.h>

int main(int argc, char **argv)
{
    char str1[]     = "123456789012345678901234567890";
    int  width      = 0;

    //...

    if(...) {
        width = 10;
    } else {
        width = 20;
    }
    printf("]%.*s]\n", width, str1);
    
    return 0;
}

  경우에 따라서는 폭을 동적으로 출력할 필요가 있습니다. 이 경우에 폭 부분을 숫자대신 *로 표시하고 폭을 parameter로 넘기면 됩니다. 위의 소스에서는 폭이 10일 때도 있고 20일 때도 있는 경우에 위와 같이 폭을 *로 처리하면 됩니다.

 

 


 

see also :  sprintf(3) snprintf(3) fprintf(3) Stream File I/O Library

 

 

블로그 이미지

사용자 자연&사람

행복한 개발자 programmer since 1995.

댓글을 달아 주세요