printf 함수 구현해보기 (4 step (final))

jukim·2021년 6월 24일
0

프로젝트

목록 보기
4/8

< 's' 구현 >

void	ft_check_str(t_list *flag, va_list ap, int *val)
{
	char *s;

	s = va_arg(ap, char *);
	if (!s)
		s = "(null)";
	if (flag->precision == -1)
		ft_str_minus_precision(s, flag, val);
	else if (flag->precision == 0)
		ft_str_zero_precision(flag, val);
	else if (flag->precision > 0)
		ft_str_plus_precision(s, flag, val);
}
  • < step 1 >
    => 문자열 가변인자를 s에 담음.
    if, s == NULL
    : s = "(null)"담음.
    else
    : s = 문자열 가변인자를 담음.

  • < step 2 >
    => precision을 기준으로 3가지 case를 만듬.
    case 1) precision이 없는 경우.
    case 2) precision == 0 인 경우.
    case 3) precision > 0 인 경우.

  • < step 3 >
    => 각각의 경우에 맞게 flag와 s를 조작하는 함수에 넣어서 출력함.

< 'c' 구현 >

void	ft_check_char(char **args, t_list *flag, va_list ap, int *val)
{
	char c;

	if (**args == '%')
		c = '%';
	else
		c = va_arg(ap, int);
	if (flag->width <= 1)
	{
		write(1, &c, 1);
		(*val)++;
	}
	else if (flag->width > 1)
		ft_char_print(c, flag, val);
}
  • < step 1 >
    => 문자 가변인자를 c에 담음.
    if, args == '%'
    : c = '%'담음.
    else
    : c에 가변인자를 담음.

  • < step 2 >
    => width를 기준으로 2가지 case를 만듬.
    case 1) width <= 1 인 경우.
    case 2) width > 1 인 경우.
    -> < step 3 >
    => 각각의 경우에 맞게 flag와 c를 조작하는 함수에 넣어서 출력 함.

< 'x', 'X', 'u' 구현 >

void	ft_check_hexu(char **args, t_list *flag, va_list ap, int *val)
{
	unsigned int	x;
	char			str_x[50];

	x = va_arg(ap, unsigned int);
	ft_putnum(args, x, str_x);
	if (flag->precision == 0 && x == 0)
		ft_hexu_check0(flag, val);
	else if (ft_strlen(str_x) >= flag->width &&
			ft_strlen(str_x) >= flag->precision)
	{
		write(1, str_x, ft_strlen(str_x));
		(*val) = (*val) + ft_strlen(str_x);
	}
	else if (ft_strlen(str_x) < flag->width ||
			ft_strlen(str_x) < flag->precision)
	{
		if (flag->precision <= ft_strlen(str_x))
			ft_hexu_check1(flag, str_x, val);
		else if (flag->precision > ft_strlen(str_x))
			ft_hexu_check2(flag, str_x, val);
	}
}
  • < step 1 >
    => unsigned int 타입의 가변인자를 x에 담음.

  • (ISSUE)
    숫자로 담았기 때문에 이 숫자를 write함수로 출력하려면 문자로 바꿔주어야 함.
    so, str_x라는 50크기의 문자형 배열을 선언해주고 여기에 ft_putnum 함수(숫자를 받아서 16진법 혹은 10진법형태('x' or 'X'면 16진법 'u'면 10진법형태)의 문자로 바꾸어 주는 함수)로 숫자를 문자로 바꾸어 배열에 넣음으로써 문자열 처럼 활용할 수 있게 만들어 줌.

  • < step 2 >
    => x에 담은 숫자의 길이를 기준으로 4가지 case를 만듬.
    case 1) precision == 0 이고 숫자가 0 인 경우.
    case 2) x의 길이가 width와 precision보다 큰 경우.
    case 3) x의 길이가 precision보다 같거나 작은 경우.
    case 4) x의 길이가 precision보다 큰 경우.

  • < step 3 >
    => 각각의 경우에 맞게 flag와 str_x를 조작하는 함수에 넣어서 출력함.

< 'd', 'i' 구현 >

void	ft_check_int(t_list *flag, va_list ap, int *val)
{
	int		d;
	int		len;
	char	int_d[50];

	d = va_arg(ap, int);
	ft_itoa(d, int_d);
	len = ft_int_len(flag, d, int_d);
	if (flag->precision == 0 && d == 0)
		ft_int_check0(flag, val);
	else if (len >= flag->width && len >= flag->precision)
		ft_int_check1(flag, d, int_d, val);
	else if (len < flag->width || len < flag->precision)
	{
		if (flag->precision < len)
			ft_int_check2(flag, d, int_d, val);
		else if (flag->precision >= len)
			ft_int_check3(flag, d, int_d, val);
	}
}
  • < step 1 >
    => int 타입의 가변인자를 d에 담음.

  • (ISSUE)
    숫자로 담았기 때문에 이 숫자를 write함수로 출력하려면 문자로 바꿔주어야 함.
    so, int_d라는 50크기의 문자형 배열을 선언해주고 여기에 ft_itoa 함수(숫자를 받아서 문자로 바꿔주는 함수)로 숫자를 문자로 바꾸어 배열에 넣음으로써 문자열 처럼 활용할 수 있게 만들어 줌.

  • < step 2 >
    = > ft_int_len 함수를 사용하여 d가 양수인지 음수인지에 따라 d의 길이설정을 다르게 해줌.

  • (ISSUE)
    d가 만약에 -13과 같은 음수이면 d의 길이가 '-' 길이를 더하여 3이 되고,
    d가 0이고 precision값이 0인 경우 d는 없는 것으로 취급되어 len이 0이 되어야 하기에
    이 점들을 고려해서 d의 길이를 설정해주는 함수를 사용함.

  • < step 3 >
    => d에 담은 숫자의 길이를 기준으로 4가지 case를 만듬.
    case 1) precision == 0 이고 숫자가 0 인 경우.
    case 2) d의 길이가 width와 precision보다 큰 경우.
    case 3) d의 길이가 precision보다 같거나 작은 경우.
    case 4) d의 길이가 precision보다 큰 경우.

  • < step 4 >
    => 각각의 경우에 맞게 flag와 int_d를 조작하는 함수에 넣어서 출력함.

< 'p' 구현 >

void	ft_check_ads(t_list *flag, va_list ap, int *val)
{
	char				ads_p[50];
	unsigned long long	p;
	int					len;

	p = va_arg(ap, unsigned long long);
	ft_puthex_long(ads_p, p);
	flag->shap_flag = 1;
	len = ft_strlen(ads_p) + 2;
	if (flag->precision == 0 && p == 0)
		ft_ads_check0(flag, val);
	else if (len >= flag->width && len >= flag->precision)
		ft_ads_check1(flag, ads_p, val);
	else if (len < flag->width || len < flag->precision)
	{
		if (flag->precision <= len)
			ft_ads_check2(flag, ads_p, len, val);
		else if (flag->precision > len)
			ft_ads_check3(flag, ads_p, len, val);
	}
}
  • < step 1 >
    => unsigned long long 타입의 가변인자를 p에 담음.

  • (ISSUE)
    숫자로 담았기 때문에 이 숫자를 write함수로 출력하려면 문자로 바꿔주어야 함.
    so, ads_p라는 50크기의 문자형 배열을 선언해주고 여기에 ft_puthex_long 함수(숫자를 받아서 16진법 형태의 문자로 바꾸어 주는 함수)로 숫자를 문자로 바꾸어 배열에 넣음으로써 문자열 처럼 활용할 수 있게 만들어 줌.
  • < step 2 >
    => flag->shap_flag 값을 1로 바꾸어 줌.
    => len에 p의 길이 + 2 값을 넣는다.

  • (ISSUE)
  1. p는 출력하게되면 앞에 '0x'라는 문자를 더하여 주소값을 출력하므로 '0x'를 출력한다는 의미로 t_list 구조체에 있는 shap_flag값을 1로 바꾸어준다.
  2. p는 '0x'뒤에 주소값이 붙어서 출력되기때문에 기본적으로 '0x'의 길이를 담고있다.
    따라서 '0x'만큼의 길이를 더한 값과 width크기값을 비교하기 때문에 '0x'길이인 2를 더해준다.
  • < step 3 >
    => p에 담은 숫자의 길이를 기준으로 4가지 case를 만듬.
    case 1) precision == 0 이고 숫자가 0 인 경우.
    case 2) p의 길이가 width와 precision보다 큰 경우.
    case 3) p의 길이가 precision보다 같거나 작은 경우.
    case 4) p의 길이가 precision보다 큰 경우.

  • < step 4 >
    => 각각의 경우에 맞게 flag와 ads_p를 조작하는 함수에 넣어서 출력함.

profile
21세기 모험가

0개의 댓글

관련 채용 정보