ft_printf

coh·2022년 8월 11일
0

42seoul

목록 보기
3/3

코드는 깃허브에 올려두었어요.

https://github.com/cheol5/코의 깃허브!

printf 의 구현을 해보기

과제를 풀기 위해서 알아야할 개념.

  1. 가변인자.
  2. man (3) printf

저는 mandatory만 구현을 했기 때문에
두 개념에 대해서만 다루었습니다.

가변인자 <man 3 stdarg>

가변인자 개념

간단하게 가변인자 개념을 먼저 살펴보는 것이 좋을 것 같습니다.
printf는 인자가 여러 개가 들어와도 처리를 해줍니다. 이와 같은 구현을 하기 위해 가변인자를 사용합니다.

#include <stdarg.h>

   void va_start(va_list ap, last);
   type va_arg(va_list ap, type);
   void va_end(va_list ap);

va_list

#if defined __GNUC__ && __GNUC__ >= 3
typedef __builtin_va_list va_list;
#else
typedef char* va_list;
#endif

GNUC는 compiler가 어떤 것인지를 나타내는 것이라고 함!
va_list는 1byte씩 이동시키기 위해서 char*의 type이다.

va_start

The argument last is the name of the last argument before the variable argument
list, that is, the last argument of which the calling function knows the type.

Because the address of this argument may be used in the va_start() macro, it should
not be declared as a register variable, or as a function or an array type.

#define va_start(ap, pN)
	((ap) = ((va_list) (&pN) + __va_argsiz(pN)))

-> 고정인자 이후의 주소로 ap를 초기화 시켜준다.

va_arg

#define va_arg(ap, t)(((ap) = (ap) + __va_argsiz(t)), *((t*) (void*) ((ap) - __va_argsiz(t))))

자료형의 크기만큼 밀어준 값을 ap에 저장하고 밀어준 값을 다시 빼줍니다. 이렇게 하는 이유는 가변인자의 자료형의 크기만큼 알맞게 밀어줄 수 있기 때문입니다.

va_end

man (3) printf

synopsis

#include <stdio.h>
int printf (const char *format, ...)

-> 고정인자와 가변인자를 받는 함수. 가변인자는 무엇인지 모르니까 ...으로 표현합니다.
1.The function of pirntf() write output to stdout.

2.return the number of characters printed
-> stdout에 output을 쓰면 되고 print한 char 갯수를 return 한다.

해결해야 했던 점.

  1. %c 출력할 때 int를
    va_arg(ap, char) -> va_arg(ap, int)

https://stackoverflow.com/questions/28054194/char-type-in-va-arg

-> 요약하면 C의 초기버전에서, 즉, 프로토타입이 도입되기 전에는 모든 함수들이 이런 방식으로 동작했다고 합니다. 이는 역사적이유와 컴파일러 작업을 쉽게 하기 위해서라고 합니다.

  1. hexa number출력
#include "./ft_printf.h"

int	ft_puthex(va_list ap, char c)
{
	size_t			len;
	char			*base;
	unsigned int	i;

	base = "0123456789abcdef";
	len = 0;
	i = 0;
	if (c == 'p')
	{
		len = (size_t)va_arg(ap, void *);
		ft_putstr("0x");
		if (!len)
		{
			write(1, "0", 1);
			return (3);
		}
		return (ft_putunbr(len, 16, base, (int *)&i) + 2);
	}
	if (c == 'x' || c == 'X')
		i = va_arg(ap, int);
	if (c == 'X')
		base = "0123456789ABCDEF";
	return (ft_putunbr(i, 16, base, (int *)&len));
}
int	ft_putunbr(size_t n, size_t bn, char *base, int *cnt)
{
	if (n >= bn)
	{
		ft_putunbr(n / bn, bn, base, cnt);
		ft_putunbr(n % bn, bn, base, cnt);
	}
	else
	{
		(*cnt)++;
		write(1, &base[n], 1);
	}
	return (*cnt);
}

hexa number 를 한번에 처리하기 위해 하나의 함수에서 처리를 했습니다.
p, x, X에 대해서 처리를 했고 base를 각 문자에 맞게 변경을 했습니다.

profile
Written by coh

0개의 댓글