42Seoul/printf

printf implement

재윤 2023. 5. 20. 15:41
반응형

Makefile

CC = gcc
CFLAGS = -Wall -Wextra -Werror
NAME = libftprintf.a
SRCS = ft_printf.c output_csp.c output_d.c output_xu.c
OBJS = $(SRCS:.c=.o)
INCLUDE = printf.h 

all: $(NAME)

$(NAME): $(OBJS)
	ar -rc $@ $(OBJS)

.c.o: $(OBJS)
	$(CC) $(CFLAGS) -c -o $@ $< -I $(INCLUDE)

clean:
	rm -f $(OBJS)

fclean: clean
	rm -f $(NAME)

re: fclean all

.PHONY: clean fclean re

ft_printf.h

#ifndef FT_PRINTF_H
# define FT_PRINTF_H

# include <stdarg.h>
# include <unistd.h>

int		ft_printf(const char *str, ...);
int		ft_printf_second(va_list vl, const char *str, int *count_num);
int		check_percent(const char *str, int i, va_list vl);
int		output_char(va_list vl);
int		output_string(va_list vl);
int		output_address_2(unsigned long long output, int *len);
int		output_address(va_list vl);
int		output_int_2(int output, int *len);
int		output_int(va_list vl);
int		output_unsignedint2(unsigned int output, int *len);
int		output_unsignedint(va_list vl);
int		output_six_smlletter(unsigned int output, int *len);
int		output_six_bigletter(unsigned int output, int *len);
int		output_six(va_list vl, char check);

#endif

ft_printf.c

#include "ft_printf.h"

int	check_percent(const char *str, int i, va_list vl)
{
	int	len;

	i++;
	len = 0;
	if (str[i] == 'c')
		len = output_char(vl);
	else if (str[i] == 's')
		len = output_string(vl);
	else if (str[i] == 'p')
		len = output_address(vl);
	else if (str[i] == 'd' || str[i] == 'i')
		len = output_int(vl);
	else if (str[i] == 'u')
		len = output_unsignedint(vl);
	else if (str[i] == 'x' || str[i] == 'X')
		len = output_six(vl, str[i]);
	else if (str[i] == '%')
	{
		if (write(1, "%%", 1) == -1)
			return (-1);
		len = 1;
	}
	return (len);
}

int	ft_printf_second(va_list vl, const char *str, int *count_num)
{
	int	i;
	int	tmp;

	i = 0;
	tmp = 0;
	while (str[i] != '\\0')
	{
		tmp = 0;
		if (str[i] == '%')
			tmp = check_percent(str, i++, vl);
		else
		{
			if (write(1, &str[i], 1) == -1)
				return (*count_num = -1);
			tmp++;
		}
		if (tmp == -1)
		{
			*count_num = tmp;
			break ;
		}
		*count_num += tmp;
		i++;
	}
	return (*count_num);
}

int	ft_printf(const char *str, ...)
{
	int		i;
	int		count_num;
	va_list	vl;

	i = 0;
	count_num = 0;
	va_start(vl, str);
	ft_printf_second(vl, str, &count_num);
	va_end(vl);
	return (count_num);
}

output_csp.c

#include "ft_printf.h"

int	output_char(va_list vl)
{
	char	alp;
	int		len;

	len = 0;
	alp = va_arg(vl, int);
	if (write(1, &alp, 1) == -1)
		return (-1);
	len++;
	return (len);
}

int	output_string(va_list vl)
{
	char	*string;
	int		len;

	len = 0;
	string = (char *)va_arg(vl, void *);
	if (string == NULL)
	{
		if (write (1, "(null)", 6) == -1)
			return (-1);
		return (6);
	}
	while (string[len])
	{
		if (write(1, &string[len], 1) == -1)
			return (-1);
		len++;
	}
	return (len);
}

int	output_address_2(unsigned long long output, int *len)
{
	int	check;

	check = 0;
	if (output > 0)
	{
		output_address_2(output / 16, len);
		check = write(1, &"0123456789abcdef"[output % 16], 1);
		(*len)++;
		if (check == -1)
		{
			*len = check;
			return (*len);
		}
	}
	return (*len);
}

int	output_address(va_list vl)
{
	unsigned long long	output;
	int					len;

	len = 2;
	output = (unsigned long long)va_arg(vl, void *);
	if (output == 0)
	{
		if (write(1, "0x0", 3) == -1)
			return (-1);
		return (++len);
	}
	if (write(1, "0x", 2) == -1)
		return (-1);
	output_address_2(output, &len);
	return (len);
}

output_d.c

#include "ft_printf.h"

int	output_int_3(int *len)
{
	if (write(1, "-2147483648", 11) == -1)
		return (*len = -1);
	return (*len = 11);
}

int	output_int_2(int output, int *len)
{
	char	math;

	if (output == -2147483648)
		return (output_int_3(len));
	else if (output < 0)
	{
		if (write(1, "-", 1) == -1)
			return (*len = -1);
		output *= -1;
		(*len)++;
		output_int_2(output, len);
	}
	else
	{
		if (output <= 0)
			return (0);
		if (output_int_2(output / 10, len) == -1)
			return (-1);
		(*len)++;
		math = output % 10 + '0';
		if (write(1, &math, 1) == -1)
			return (*len = -1);
	}
	return (*len);
}

int	output_int(va_list vl)
{
	int			output;
	int			len;

	len = 0;
	output = va_arg(vl, int);
	if (output == 0)
	{
		if (write (1, "0", 1) == -1)
			return (-1);
		len++;
		return (len);
	}
	output_int_2(output, &len);
	if (len == -1)
		return (-1);
	return (len);
}

output_xu.c

#include "ft_printf.h"

int	output_unsignedint2(unsigned int output, int *len)
{
	char	one_output_char;

	if (*len == -1)
		return (-1);
	if (output > 0)
	{
		if (output_unsignedint2(output / 10, len) == -1)
			return (*len = -1);
		(*len)++;
		one_output_char = (output % 10) + '0';
		if (write(1, &one_output_char, 1) == -1)
			return (*len = -1);
	}
	return (*len);
}

int	output_unsignedint(va_list vl)
{
	unsigned int	output;
	int				len;
	char			output_char;

	len = 0;
	output = va_arg(vl, unsigned int);
	if (output == 0)
	{
		output_char = output + '0';
		if (write(1, &output_char, 1) == -1)
			return (-1);
		len++;
		return (len);
	}
	output_unsignedint2(output, &len);
	if (len == -1)
		return (-1);
	return (len);
}

int	output_six_smlletter(unsigned int output, int *len)
{
	if (output > 0)
	{
		if (output_six_smlletter(output / 16, len) == -1)
			return (*len = -1);
		if (write(1, &"0123456789abcdef"[output % 16], 1) == -1)
			return (*len = -1);
		(*len)++;
	}
	return (*len);
}

int	output_six_bigletter(unsigned int output, int *len)
{
	if (output > 0)
	{
		if (output_six_bigletter(output / 16, len) == -1)
			return (*len = -1);
		if (write(1, &"0123456789ABCDEF"[output % 16], 1) == -1)
			return (*len = -1);
		(*len)++;
	}
	return (*len);
}

int	output_six(va_list vl, char check)
{
	unsigned int	output;
	char			output_char;
	int				len;

	len = 0;
	output = (unsigned int)va_arg(vl, unsigned int);
	if (output == 0)
	{
		output_char = output + '0';
		if (write(1, &output_char, 1) == -1)
			return (-1);
		len++;
		return (len);
	}
	if (check == 'x')
		output_six_smlletter(output, &len);
	else if (check == 'X')
		output_six_bigletter(output, &len);
	return (len);
}
반응형

'42Seoul > printf' 카테고리의 다른 글

가변 인자(va_start, va_arg, va_copy, va_end)  (0) 2023.05.20
printf 반환형(반환형이 왜 int일까?)  (0) 2023.05.20