[ft_print] Printf_Mandatory 함수 구현 과정

Cadet_42·2021년 8월 4일
0

ft_printf

목록 보기
4/6
post-thumbnail

Ft_printf 함수 구현 과정

  1. int ft_printf(const char *str, ...) 함수 안에서 %를 찾는 즉시, 해당되는 type 형태에 cspdiuxX%따라 해당 값을 출력한다. (먼저, 모든 type값을 출력하는 하나의 함수를 만든 후, optimize 필요 여부에 따라 함수들을 쪼개는 형식으로 진행 했다.)

  2. 과제에서 주어진 int ft_printf(const char *str, ...)를 사용하기 위해서, type에 따라 출력되는 함수에 int printchar(const char **str, va_list ap)를 거의 적용하였다.

  • **str : 문자열의 포인터
  • va_list : 가변 인자 목록 포인터
  1. printf 함수의 반환 type은 int이며, 출력되는 문자의 개수를 반환한다. 출력되는 문자의 개수는 공백(), 개행(\n), 가로 탭(\t)등을 포함한다.

❗️ va_arg 가변 인자 포인터 값을 이용하여, printf와 같은 리턴값을 출력했다.

❗️ 주의점, printf\n을 1바이트로 인식하고 반환시 값을 포함한다. %d와 같이 % 의 값은 바이트로도 인식하지 않고, 반환시 값을 포함하지도 않는다.

❗️ 내가 작성한 ft_printf함수는 %d 값이 있을시, 퍼센트와 해당 type의 바이트를 인식해줘야 하기 때문에, 반환 값 출력시, 해당 바이트인 2바이트를 항상 빼줘야 한다.

  1. malloc을 써준 함수들은 memory leaks 와 같은 오류를 방지하기 위해 free를 꼭 해줘야 한다.

💡 printf 반환값 예시

#include <stdio.h>
int main(void)
{
	int re; // printf의 리턴type은 int다!
	int se;
	char c = 'H';
	char *s = "FOUR";
	
	printf("**********print  C********\n");
	re = printf("%c\n",c);
	printf("re: %d\n", re);

	se = ft_printf("%c\n",c);
	printf("se: %d\n", se);
	
	int ke;
	int te;

	printf("********print S********\n");
	te = printf("Real%s\n", s); // '\n' = 1 byte 
	printf("te: %d\n", te);
	
	ke = ft_printf("Mine%s\n", s); // 내 함수는 % (1 byte), s (1 byte)로 받으므로 %s 에 해당하는 2바이트를 -2로 빼줘야 한다.
	printf("ke: %d\n", ke);

	return (0);
	}

💡 출력값

**********print  C********
H
re: 2
H
se: 2
********print S********
RealFOUR
te: 9
MineFOUR
ke: 9

ft_printf.c 함수


#include "ft_printf.h"

int	printchar(const char **str, va_list ap) // **str = *str의(문자열) 포인터
{
	int		i;

	while (**str)
	{
		if ((char) **str == 'c')
		{
			i = va_arg(ap, int); // 가변인자 포인터에서 특정 자료형 크기만큼 값을 가져옴. 여기서는 int의 크기를 가져옴.
			write(1, &i, 1);
			(*str)++;
			return (1); // return(1)은 c 의 1바이트를 의미한다. 
		}
		else if ((char)**str == 's')
			return (print_s(str, ap));
		else if ((char)**str == 'x' || (char)**str == 'X' || (char)**str == 'p')
			return (print_num(str, ap));
		else if ((char)**str == 'd' || (char)**str == 'i')
			return (print_di(str, ap));
		else if ((char)**str == 'u')
			return (print_u(str, ap));
		else
			return (printpercent(str));
	}
	return (0);
}

int	ft_printf(const char *str, ...)
{
	va_list ap; // argument pointer 가변인자 목록 포인터 (가변인자의 메모리 주소저장.)
	int		len;

	va_start(ap, str); // 가변인자 목록 포인터 설정
	len = ft_strlen(str); // str의 길이
	while (*str) // *str 끝까지 반복한다. 
	{
		if (*str == '%') // '%'를 발견하는 즉시, printchar를 출력한다.
		{
			str++;
			len += printchar(&str, ap) - 2; // -2는 (%d, %c 등 %와 알파벳을 포함한 2바이트를 의미한다)
		}
		else // str == %를 찾지 못한경우, str를 ++ 하면서 찾는다. 
		{
			write(1, str, 1);
			str++;
		}
	}
	va_end(ap); // 가변인자 처리가 끝났을떄 포인터를 null로 초기화.
	return (len); // printf 의 리턴값은 int (길이) 이므로
}
profile
안녕하세요! 개발공부를 하고 있습니다. 감사히 배우겠습니다. ;)

0개의 댓글