C언어/잡학사전

[C언어] 서식 지정자의 모든것 (서식문자)

아무일도없었다 2022. 8. 9. 01:09

서식 지정자 ?

printf, scanf, sprintf, fprintf 등의 여러 API 에서 가변인자를 받아서 처리하기 위한 데이터 포맷이다.
가변인자를 처리하는 API 함수 내부에서 어떤 인자를 어떤식으로 처리할지 지정하기 위해서 사용한다.

 

잡학사전

여러 API 에서 가변인자를 서식 지정자를 통해 처리하는데 printf 와 scanf 만 비교해봐도 서식 지정자로 특정할 수 있는 자료형의 스펙이 조금씩 다르다.

printf 는 타입을 전달받아 데이터를 출력하기 때문에 형변환(type casting)형승격(type promotion) 을 통해 크기가 다른 타입에 대해서 유연한 메모리 처리가 가능하지만, scanf 는 포인터를 전달받아 입력받은 데이터를 저장하기 때문에 서식 지정자에 의존하여 메모리 처리를 할 수 밖에 없는 구조이다. (ex: printf 의 %f 는 float (4byte) 과 double (8byte) 의 출력처리가 모두 가능하지만 scanf 의 %f 는 float (4byte) 처리만 가능하고 double (8byte) 은 %lf 로 처리해야한다.)

따라서 printf 같이 유연한 가변인자 처리보다는 scanf 같이 정확한 가변인자 처리에 대한 서식 지정자를 사용하는게 잠재적 버그를 줄이는 방법중에 하나이다. (ex: short : %d 보다는 %hd 를 사용, double : %f 보다는 %lf 를 사용)

 

서식 지정자

※ int = 4byte, long = 8 byte 로 생각한다면 잠시 여기를 먼저 보는걸 추천한다.

서식 지정자 자료형 의미
%c char 문자
%s char*, char[] 문자열
%hd short 부호를 포함한 2byte 크기의 정수 (10진수)
%d int 부호를 포함한 int 타입 크기의 정수 (10진수)
%ld long 부호를 포함한 long 타입 크기의 정수 (10진수)
%lld long long 부호를 포함한 8byte 크기의 정수 (10진수)
%hi short 부호를 포함한 2byte 크기의 정수 (10진수)
%i int 부호를 포함한 int 타입 크기의 정수 (10진수)
%li long 부호를 포함한 long 타입 크기의 정수 (10진수)
%lli long long 부호를 포함한 8byte 크기의 정수 (10진수)
%hu unsigned short 부호를 포함하지 않는 2byte 크기의 정수 (10진수)
%u unsigned int 부호를 포함하지 않는 int 타입 크기의 정수 (10진수)
%lu unsigned long 부호를 포함하지 않는 long 타입 크기의 정수 (10진수)
%llu unsigned long long 부호를 포함하지 않는 8byte 크기의 정수 (10진수)
%ho unsigned short 부호를 포함하지 않는 2byte 크기의 정수 (8진수)
%o unsigned int 부호를 포함하지 않는 int 타입 크기의 정수 (8진수)
%lo unsigned long 부호를 포함하지 않는 long 타입 크기의 정수 (8진수)
%llo unsigned long long 부호를 포함하지 않는 8byte 크기의 정수 (8진수)
%hx unsigned short 부호를 포함하지 않는 2byte 크기의 정수 (16진수, abcdef 를 소문자로 표기)
%x unsigned int 부호를 포함하지 않는 int 타입 크기의 정수 (16진수, abcdef 를 소문자로 표기)
%lx unsigned long 부호를 포함하지 않는 long 타입 크기의 정수 (16진수, abcdef 를 소문자로 표기)
%llx unsigned long long 부호를 포함하지 않는 8byte 크기의 정수 (16진수, abcdef 를 소문자로 표기)
%hX unsigned short 부호를 포함하지 않는 2byte 크기의 정수 (16진수, ABCDEF 를 대문자로 표기)
%X unsigned int 부호를 포함하지 않는 int 타입 크기의 정수 (16진수, ABCDEF 를 대문자로 표기)
%lX unsigned long 부호를 포함하지 않는 long 타입 크기의 정수 (16진수, ABCDEF 를 대문자로 표기)
%llX unsigned long long 부호를 포함하지 않는 8byte 크기의 정수 (16진수, ABCDEF 를 대문자로 표기)
%f float 소수점으로 표현한 4byte 크기의 실수 (10진수)
%lf double 소수점으로 표현한 8byte 크기의 실수 (10진수)
%llf , %Lf long double 소수점으로 표현한 long double 타입 크기의 실수 (10진수)
%e float 지수 표기법으로 표현한 4byte 크기의 실수 (10진수, 소문자 e)
%le double 지수 표기법으로 표현한 8byte 크기의 실수 (10진수, 소문자 e)
%Le long double 지수 표기법으로 표현한 long double 타입 크기의 실수 (10진수, 소문자 e)
%E float 지수 표기법으로 표현한 4byte 크기의 실수 (10진수, 대문자 E)
%lE double 지수 표기법으로 표현한 8byte 크기의 실수 (10진수, 대문자 E)
%LE long double 지수 표기법으로 표현한 long double 타입 크기의 실수 (10진수, 대문자 E)
%g float %f 와  %e 둘중에 짧은 길이로 표현되는 서식 지정자를 사용 (소문자 e)
%lg double %lf 와 %le 둘중에 짧은 길이로 표현되는 서식 지정자를 사용 (소문자 e)
%Lg long double %Lf 와 %Le 둘중에 짧은 길이요 표현되는 서식 지정자를 사용 (소문자 e)
%G float %f 와 %e 둘중에 짧은 길이로 표현되는 서식 지정자를 사용 (대문자 E)
%lG double %lf 와 %le 둘중에 짧은 길이로 표현되는 서식 지정자를 사용 (대문자 E)
%LG long double %Lf 와 %Le 둘중에 짧은 길이로 표현되는 서식 지정자를 사용 (대문자 E)

 

printf 출력시 사용가능한 추가적인 서식 지정자 & 플래그

서식 지정자 자료형 의미
%a float 지수 표기법으로 표현한 4byte 크기의 실수 (16진수, 소문자 p)
%la double 지수 표기법으로 표현한 8byte 크기의 실수 (16진수, 소문자 p)
%La long double 지수 표기법으로 표현한 long double 타입 크기의 실수 (16진수, 소문자 p)
%A float 지수 표기법으로 표현한 4byte 크기의 실수 (16진수, 대문자 P)
%lA double 지수 표기법으로 표현한 8byte 크기의 실수 (16진수, 대문자 P)
%LA long double 지수 표기법으로 표현한 long double 타입 크기의 실수 (16진수, 대문자 P)

 

플래그 의미
%숫자 숫자만큼 폭을 지정해서 출력한다. (기본 오른쪽 정렬)
%.숫자 온점 (.) 뒤쪽의 숫자만큼 소수점 자리수를 조절한다. (나머지는 반올림)
%- 왼쪽 정렬
%+ 기본적으로 음수일때만 표현되던 부호를 양수에서도 표현한다. (양수일 경우 + 부호)
%# 출력되는 숫자 앞에 진법 표기를 하고 실수의 경우 소수점을 강제로 붙인다.
(%#o , %#x, %#X , %#f, %#e, %#E, %#g, %#G)
%0숫자 숫자만큼 폭을 지정하고 빈 칸을 0으로 채운다.

 

<소스코드>

printf("%10d %10d\n", 1234, 5678); // 폭을 10으로 잡고 오른쪽 정렬
printf("%-10d %-10d\n", 1234, 5678); // 폭을 10으로 잡고 왼쪽 정렬
printf("%.3f\n", 1.234567f); // 소수점 3자리까지 반올림
printf("%+10d\n", 1234); // 폭을 10으로 잡고 부호를 표기
printf("%010d\n", 5678); // 폭을 10으로 잡고 빈공간을 0으로 채움
printf("%#x\n", 1234); // 1234를 0x로 시작하는 16진수로 표기

< 출력 >

      1234      5678
1234      5678      
1.235
     +1234
0000005678
0x4d2

※ 폭을 확인하기 위해 검정색 배경 사용

반응형