소프트웨어/알아두면 좋은 것들

printf , sprintf , fprintf 서식 문자 완벽 정리 (%d, %f, %o, %n)

리습 2021. 4. 5. 06:30

안녕하세요 리습입니다.

 자주는 아니지만, 아주 가~끔 은 기억이 안 나서 찾아보게 되는 printf 들(sprintf, fprintf)의 서식 문자에 대하여 완벽하게 정리해보도록 하겠습니다.

 우선 많이 사용하는 서식 문자에 대하여 요약 정리를 하면 다음과 같습니다. 가장 많이 사용하는 %d, %u, %o, %x, %f, %e 에 대하여 정리하였습니다. 또한 적절한 입력 변수 타입을 함께 표기하여, 현재 본인이 사용하고 있는 변수에 알맞은 서식 문자를 찾기 쉽도록 표기하였습니다. 

printf 서식 문자 총정리

이 외에도 printf, sprintf, fprintf에는 다양한 옵션들이 있습니다. 이에 대하여 더 자세히 알아보도록 하겠습니다. 

서식 문자 와 크기 옵션

우선 서식 문자의 정확한 형태는 다음과 같이 일반화할 수 있습니다.

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

아직은 이 형식에 익숙하지 않으니 하나씩 알아보도록 하겠습니다.

 우선 표현하고 싶은 타입 별 서식 문자는 위에서 나열한 표와 같이 %d(정수형 signed 10진수), %u(정수형 unsigned 10진수), %f(실수형 10진수)로 사용할 수 있습니다.  이것이 바로 specifier입니다.

 그런데 자세히 보시면 앞에 공통적으로 hh, h, l, ll이 붙어 있는 것을 볼 수 있습니다. 이 접두사들은 입력 변수의 크기를 결정해 줍니다. 기본적인 형식들은, int, double과 같은 형태에 맞추어져 있기 때문에 long long과 같이 크기가 큰 변수를 입력해 주기 위해서는 ll과 같은 접두사를 붙여 주어야 합니다. hh는 보통 char변수에, h는 short변수에, l은 long변수에 ll은 long long 변수를 사용할 때 붙여 주어야 합니다. 이것이 바로 [length]입니다.

 

출력 값의 기호 표기와 자릿수

  실수의 경우 어느 정도의 정밀도로 표기를 할지 결정할 필요가 있습니다. 이럴 때 사용하는 옵션이 바로 [.percision]입니다. 예를 들어 소수 두 번째 자릿수까지 표기하고 싶다면 다음과 은 코드를 작성할 수 있습니다.

printf("%.2f", 1.2345); // output : 1.23

이렇게 작성할 경우 1.23이 출력되게 됩니다. 또한 이 정확도는 외부 변수를 통해서도 조절할 수 있습니다.

int prec = 3;
printf("%.*f", prec, 1.2345); // output : 1.234

이렇게 작성된 코드는 1.234를 출력하게 됩니다. 그럼 [.percision] 옵션에 대하여 정리를 하면 다음과 같습니다.

[.persision] 옵션의 사용 방법

 만약 전체적인 출력 길이를 결정하고 싶다면 어떻게 해야 할까요? 바로 [width] 옵션을 사용하면 됩니다. width는 다음과 같이 사용할 수 있습니다.

printf("%6d is number", 123); // output :   123 is number

123이라는 숫자가 6칸에 맞추어 빈칸으로 출력되는 것을 확인 가능합니다. 즉 숫자의 간격을 유지하면서 출력하고 싶다면 위 숫자를 활용할 수 있겠죠. 그리고 width 옵션 또한 외부 변수를 통해 조절이 가능합니다. persicion과 같이 '*'을 사용하면 됩니다.

int width = 6;
printf("%*d is number", width,123); // output :   123 is number

자 그럼 width 옵션은 다음과 같이 정리할 수 있습니다.

[width] 옵션의 사용 방법

기타 고급 옵션 Flag 알아보기

printf, sprintf, fprintf에는 마지막으로 [flag]라는 옵션이 있습니다. 위 옵션은 부호를 표현하거나, 왼쪽 정렬을 통해 출력을 할 때 사용할 수 있습니다. 예를 들어 위에서 [width] 옵션을 통해 123을 출력하였을 때, 오른쪽 정렬로 "   123"로 출력되던 값을 "123   "로 바꾸어 주기 위해서는 '-'라는 옵션을 사용해야 합니다.

int width = 6;
printf("%-*d is number", width,123); // output :123    is number

혹은 16진수, 8진수를 표기할 때 0x 등 을 붙여주기 위해서는 '#'옵션을 사용해야 합니다.

printf("%#x", 243); // output : 0xf3

이 외에도 부호의 표기, 빈 공간을 0으로 채우기 등 다양한 옵션이 있으며 이러한 옵션들을 정리하면 다음과 같습니다.

[flag] 옵션의 사용 방법

마무리

서식 문자는 자주 사용하면서도 조금만 다른 형태로 사용하려고 하면 헷갈리는 기능인 것 같습니다. 이번 정리를 통해 헷갈릴 때마다 리마인드용으로 잘 사용하셨으면 하는 바람입니다.

아래는 test용 예시 코드를 드립니다.

#include <stdio.h>

int main(void) {
	// 정수형 signed 10진수
	printf("signed decimal\n");

	int				int_val				= 2147483647;
	signed char		signed_char_val		= 127;
	short int		short_int_val		= 32767;
	long int		long_int_val		= 2147483647;
	long long int	long_long_int_val	= 4611686018427387903;

	printf("%d\n", int_val);
	printf("%hhd\n", signed_char_val);
	printf("%hd\n", short_int_val);
	printf("%ld\n", long_int_val);
	printf("%lld\n", long_long_int_val);

	// 정수형 unsigned 10진수
	printf("\nunsgiend decimal\n");

	unsigned int			unsgiend_int_val = 4294967295;
	unsigned char			unsigned_char_val = 255;
	unsigned short int		unsigned_short_int_val = 65535;
	unsigned long int		unsigned_long_int_val = 4294967295;
	unsigned long long int	unsigned_long_long_int_val = 0xFFFFFFFFFFFFFFFF;

	printf("%u\n", unsgiend_int_val);
	printf("%hhu\n", unsigned_char_val);
	printf("%hu\n", unsigned_short_int_val);
	printf("%lu\n", unsigned_long_int_val);
	printf("%llu\n", unsigned_long_long_int_val);

	printf("\nunsgiend octal\n");
	printf("%o\n", unsgiend_int_val);
	printf("%hho\n", unsigned_char_val);
	printf("%ho\n", unsigned_short_int_val);
	printf("%lo\n", unsigned_long_int_val);
	printf("%llo\n", unsigned_long_long_int_val);

	printf("\nunsgiend hexadecimal\n");
	printf("%x\n", unsgiend_int_val);
	printf("%hhx\n", unsigned_char_val);
	printf("%hx\n", unsigned_short_int_val);
	printf("%lx\n", unsigned_long_int_val);
	printf("%llx\n", unsigned_long_long_int_val);

	printf("\ndecimal floating point\n");
	printf("%f\n", 1.23456);
	printf("%e\n", 1.23456);
	printf("%a\n", 1.23456);


	printf("\nString\n");
	char char_val = 'a';
	const char* string_val = "hello";
	printf("%c\n", char_val);
	printf("%s\n", string_val);
	printf("%p\n", string_val);

	printf("%6d is number", 123); // output : 123    is number

	printf("%#d", 243); // output : 0xF3

	return 0;
}