ft_printf - KimTaebin-ai/study_posts GitHub Wiki

ํ•„์š” ๊ฐœ๋… ๋ฐ ํ•™์Šต ๋‚ด์šฉ

ํ…Œ์ŠคํŠธ์ฝ”๋“œ

int	main(void)
{
	int test_result;
	char *null_str;
	char *empty_str;
	int num;
	void *ptr;
	void *null_ptr = NULL;
	char *long_str;
	unsigned int u_num;

	null_str = NULL;
	empty_str = "";
	num = 42;
	u_num = UINT_MAX;
	ptr = #
	// ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค 1: %c - ๋ฌธ์ž ์ถœ๋ ฅ
	test_result = ft_printf("1. %c\n", 'A');
	printf("Expected length: %d\n", test_result); // ์˜ˆ์ƒ ์ถœ๋ ฅ: "1. A\n" (๊ธธ์ด 5)
	// ํ…Œ์ŠคํŠธ 1-2: %c์— ASCII ์ฝ”๋“œ ๋„ฃ๊ธฐ
	ft_printf("1-2. %c\n", 65); // ์˜ˆ์ƒ ์ถœ๋ ฅ: "1-2. A\n"
	// ํ…Œ์ŠคํŠธ 1-3: %c์— ๋ฌธ์ž์—ด์„ ๋„ฃ์—ˆ์„ ๋•Œ (๋น„์ •์ƒ์ ์ธ ์ž…๋ ฅ)
	ft_printf("1-3. %c\n", "ใ…Žใ…‡"); // ์˜ˆ์ƒ ๋™์ž‘: ๋น„์ •์ƒ ๋™์ž‘ (์ปดํŒŒ์ผ๋Ÿฌ ๊ฒฝ๊ณ  ๋˜๋Š” ์˜ค๋ฅ˜)
	// ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค 2: %s - ๋ฌธ์ž์—ด ์ถœ๋ ฅ
	ft_printf("2. %s\n", "Hello, 42!"); // ์˜ˆ์ƒ ์ถœ๋ ฅ: "2. Hello, 42!\n"
	// ํ…Œ์ŠคํŠธ 2-1: %s์— ๋นˆ ๋ฌธ์ž์—ด ์ „๋‹ฌ
	ft_printf("2-1. %s\n", empty_str); // ์˜ˆ์ƒ ์ถœ๋ ฅ: "2-1. \n"
	// ํ…Œ์ŠคํŠธ 2-2: %s์— NULL ํฌ์ธํ„ฐ ์ „๋‹ฌ
	ft_printf("2-2. %s\n", null_str); // ์˜ˆ์ƒ ์ถœ๋ ฅ: "2-2. (null)\n"
	// ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค 3: %p - ํฌ์ธํ„ฐ ์ถœ๋ ฅ
	ft_printf("3. %p\n", ptr); // ์˜ˆ์ƒ ์ถœ๋ ฅ: ํฌ์ธํ„ฐ ์ฃผ์†Œ๊ฐ’
	printf("3. %p\n", ptr);    // ๋น„๊ต์šฉ ํ‘œ์ค€ printf ์ถœ๋ ฅ

	// **ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค 3-1: %p์— NULL ํฌ์ธํ„ฐ ์ „๋‹ฌ**
	ft_printf("3-1. %p\n", null_ptr); // ์˜ˆ์ƒ ์ถœ๋ ฅ: "3-1. (nil)\n"
	printf("3-1. %p\n", null_ptr);    // ๋น„๊ต์šฉ ํ‘œ์ค€ printf ์ถœ๋ ฅ

	// ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค 4: %d - ์ •์ˆ˜ ์ถœ๋ ฅ
	ft_printf("4. %d\n", num); // ์˜ˆ์ƒ ์ถœ๋ ฅ: "4. 42\n"
	// ํ…Œ์ŠคํŠธ 4-1: %d์— ์Œ์ˆ˜ ์ „๋‹ฌ
	ft_printf("4-1. %d\n", -123); // ์˜ˆ์ƒ ์ถœ๋ ฅ: "4-1. -123\n"
	// ํ…Œ์ŠคํŠธ 4-2: %d์— INT_MAX ์ „๋‹ฌ
	ft_printf("4-2. %d\n", INT_MAX); // ์˜ˆ์ƒ ์ถœ๋ ฅ: "4-2. 2147483647\n"
	// ํ…Œ์ŠคํŠธ 4-3: %d์— INT_MIN ์ „๋‹ฌ
	ft_printf("4-3. %d\n", INT_MIN); // ์˜ˆ์ƒ ์ถœ๋ ฅ: "4-3. -2147483648\n"
	// ํ…Œ์ŠคํŠธ 4-4: %d์— str ์ „๋‹ฌ
	ft_printf("4-4. %d\n", "test"); // ์˜ˆ์ƒ ์ถœ๋ ฅ:
	// ํ…Œ์ŠคํŠธ 4-5: %d์— 0 ์ „๋‹ฌ
	ft_printf("4-5. %d\n", 0); // ์˜ˆ์ƒ ์ถœ๋ ฅ: 0
	// ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค 5: %i - ์ •์ˆ˜ ์ถœ๋ ฅ (์ •์ˆ˜ํ˜• ๋™์ผ)
	ft_printf("5. %i\n", num);   // ์˜ˆ์ƒ ์ถœ๋ ฅ: "5. 42\n"
									// ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค 6: %u - ๋ถ€ํ˜ธ ์—†๋Š” ์ •์ˆ˜ ์ถœ๋ ฅ
	ft_printf("6. %u\n", u_num); // ์˜ˆ์ƒ ์ถœ๋ ฅ: "6. 4294967295\n"
	// ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค 7: %x - 16์ง„์ˆ˜ (์†Œ๋ฌธ์ž) ์ถœ๋ ฅ
	ft_printf("7. %x\n", num); // ์˜ˆ์ƒ ์ถœ๋ ฅ: "7. 2a\n"
	// ํ…Œ์ŠคํŠธ 7-1: %x์— 0 ์ „๋‹ฌ
	ft_printf("7-1. %x\n", 0); // ์˜ˆ์ƒ ์ถœ๋ ฅ: "7-1. 0\n"
	// ํ…Œ์ŠคํŠธ 7-2: %x์— UINT_MAX ์ „๋‹ฌ
	ft_printf("7-2. %x\n", UINT_MAX); // ์˜ˆ์ƒ ์ถœ๋ ฅ: "7-2. ffffffff\n"
	// ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค 8: %X - 16์ง„์ˆ˜ (๋Œ€๋ฌธ์ž) ์ถœ๋ ฅ
	ft_printf("8. %X\n", num); // ์˜ˆ์ƒ ์ถœ๋ ฅ: "8. 2A\n"
	// ํ…Œ์ŠคํŠธ 8-2: %x์— UINT_MAX ์ „๋‹ฌ
	ft_printf("8-2. %X\n", UINT_MAX); // ์˜ˆ์ƒ ์ถœ๋ ฅ: "8-2. FFFFFFFF\n"
	// ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค final: ๋‹ค์–‘ํ•œ ํ˜•์‹ ์กฐํ•ฉ
	ft_printf("final. Char: %c, String: %s, Int: %d, Hex: %x\n", 'B',
		"42Gyeongsan", 123, 255);
	// ์˜ˆ์ƒ ์ถœ๋ ฅ: "final. Char: B, String: 42Gyeongsan, Int: 123, Hex: ff\n"
	// ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค ์ถ”๊ฐ€: ๋„“์€ ํฌ์ธํ„ฐ์™€ ๋ฌธ์ž์—ด ์กฐํ•ฉ ํ…Œ์ŠคํŠธ
	long_str = "This is a longer string to test";
	ft_printf("real final: Ptr: %p, Long Str: %s\n", long_str, long_str);
	// ์˜ˆ์ƒ ์ถœ๋ ฅ: ํฌ์ธํ„ฐ์™€ ๋ฌธ์ž์—ด์ด ์ •์ƒ ์ถœ๋ ฅ

	return (0);
}

// cc -Wall -Wextra -Werror -o test ft_printf.c -L. libftprintf.a
// ./test

Makefile ์—…๊ทธ๋ ˆ์ด๋“œ

%.o : %.c
    cc $(CFLAGS) -c $< -o $@

์†Œ์Šค ํŒŒ์ผ์ด ๋ณ€๊ฒฝ๋œ ๊ฒฝ์šฐ์—๋งŒ ํ•ด๋‹น .o ํŒŒ์ผ์„ ๋‹ค์‹œ ์ปดํŒŒ์ผํ•œ๋‹ค
$(NAME): $(OBJS)
    $(MAKE) -C ./libft
    cp  ./libft/libft.a $(NAME)
    ar -rcs $@ $^

.o($^)์ด ๋ณ€๊ฒฝ๋œ ๊ฒฝ์šฐ์—๋งŒ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ($@)๋ฅผ ๋‹ค์‹œ ์ƒ์„ฑํ•œ๋‹ค.

ํ’€์ด

ft_printf.c

#include "ft_printf.h"
#include <stdio.h>

int	check_type(const char *bs, va_list ap)
{
	if (*bs == 'c')
		return (c_func(ap));
	else if (*bs == 's')
		return (s_func(ap));
	else if (*bs == 'p')
		return (p_func(ap));
	else if (*bs == 'd' || *bs == 'i')
		return (d_func(ap));
	else if (*bs == 'u')
		return (u_func(ap));
	else if (*bs == 'x')
		return (sx_func(ap));
	else if (*bs == 'X')
		return (lx_func(ap));
	else
		return (-1); // ์˜ค๋ฅ˜  ๋ฐœ์ƒ์‹œ -1 ๋ฆฌํ„ด
}

int	count_bs(const char *bs, va_list ap)
{
	int	i;
	int	type_len;

	i = 0;
	while (*bs)
	{
		if (*bs == '%')
		{
			bs++; // %๋’ค ํƒ€์ž… ํ™•์ธ ๋ชฉ์ 
			type_len = check_type(bs, ap);
			if (type_len == -1) // ๋„๊ฐ€๋“œ ํ•„์š”
				return (-1);
			i += type_len;
		}
		else
		{
			if (write(1, bs, 1) == -1)
			{
				return (-1);
			}
			i++;
		}
		bs++;
	}
	return (i);
}

int	ft_printf(const char *bs, ...)
{
	va_list	argptr;
	int		bs_len;

	bs_len = 0;
	va_start(argptr, bs);
	bs_len = count_bs(bs, argptr);
	return (bs_len);
}

func.c

#include "ft_printf.h"

int	c_func(va_list ap)
{
	char	c;

	c = (char)va_arg(ap, int);
	if (write(1, &c, 1) == -1)
		return (-1);
	return (1);
}

int	s_func(va_list ap)
{
	char	*s;

	s = va_arg(ap, char *);
	if (s == NULL)
	{
		write(1, "(null)", 6);
		return (6);
	}
	if (write(1, s, ft_strlen(s)) == -1 || ft_strlen(s) > INT_MAX)
		return (-1);
	return (ft_strlen(s));
}

int	p_func(va_list ap)
{
	void				*ptr;
	unsigned long long	p;
	char				*pitoa;
	int					len;

	ptr = va_arg(ap, void *);
	if (ptr == NULL)
	{
		return (write(1, "(nil)", 5));
	}
	p = (unsigned long long)ptr;
	pitoa = ft_itoahex(p, "0123456789abcdef");
	len = ft_strlen(pitoa);
	write(1, "0x", 2);
	if (write(1, pitoa, len) == -1)
	{
		free(pitoa);
		return (-1);
	}
	free(pitoa);
	return (len + 2);
}

int	d_func(va_list ap)
{
	int		d;
	char	*ditoa;
	int		len;

	d = va_arg(ap, int);
	ditoa = ft_itoa(d);
	len = ft_strlen(ditoa);
	if (write(1, ditoa, len) == -1)
	{
		free(ditoa);
		return (-1);
	}
	free(ditoa);
	return (len);
}

int	u_func(va_list ap)
{
	unsigned int	u;
	char			*uitoa;
	int				len;

	u = va_arg(ap, unsigned int);
	uitoa = ft_itoa(u);
	len = ft_strlen(uitoa);
	if (write(1, uitoa, len) == -1)
	{
		free(uitoa);
		return (-1);
	}
	free(uitoa);
	return (len);
}

func2.c

int	x_func(va_list ap, const char *hex)
{
	unsigned int	x;
	char			*xitoa;
	int				len;
	int				write_result;

	x = va_arg(ap, unsigned int);
	xitoa = ft_itoahex(x, hex);
	HANDLE_ERROR(!xitoa, return (-1));
	len = 0;
	while (xitoa[len])
		len++;
	write_result = write(1, xitoa, len);
	free(xitoa);
	HANDLE_ERROR(write_result == -1, return (-1));
	return (len);
}

int	sx_func(va_list ap)
{
	return (x_func(ap, HEX_CHARS_LOWER));
}

int	lx_func(va_list ap)
{
	return (x_func(ap, HEX_CHARS_UPPER));
}

convert_hex.c

#include "ft_printf.h"

int	sizen_h(unsigned long long n)
{
	int	i;

	i = 0;
	if (n == 0)
		i = 1;
	else
	{
		while (n)
		{
			n = n / 16;
			i++;
		}
	}
	return (i);
}

char	*ft_itoahex(unsigned long long n)
{
	int					size_n;
	char				*ia;
	char				*hex;
	unsigned long long	fn;

	size_n = sizen_h(n);
	ia = (char *)ft_calloc((size_n + 1), sizeof(char));
	if (ia == NULL)
		return (0);
	hex = "0123456789abcdef";
	fn = n;
	while (fn)
	{
		ia[size_n - 1] = *(hex + (fn % 16));
		fn = fn / 16;
		size_n--;
	}
	if (n == 0)
		ia[0] = '0';
	return (ia);
}
char	*ft_itoahex_large(unsigned long long n)
{
	int					size_n;
	char				*ia;
	char				*hex;
	unsigned long long	fn;

	size_n = sizen_h(n);
	ia = (char *)ft_calloc((size_n + 1), sizeof(char));
	if (ia == NULL)
		return (0);
	hex = "0123456789ABCDEF";
	fn = n;
	while (fn)
	{
		ia[size_n - 1] = *(hex + (fn % 16));
		fn = fn / 16;
		size_n--;
	}
	if (n == 0)
		ia[0] = '0';
	return (ia);
}
NAME = libftprintf.a

SRCS = ft_printf.c func.c func2.c convert_hex.c

OBJS = $(SRCS:%.c=%.o)

CFLAGS = -Wall -Wextra -Werror -I.

all : $(NAME)
$(NAME): $(OBJS)
	$(MAKE) -C ./libft
	cp  ./libft/libft.a $(NAME)
	ar -rcs $@ $^
	
%.o : %.c
	cc $(CFLAGS) -c $< -o $@

clean :
	$(MAKE) -C ./libft clean
	rm -f $(OBJS)

fclean :
	$(MAKE) -C ./libft fclean
	make clean
	rm -f $(NAME) 

re : 
	make fclean
	make all

.PHONY : all clean fclean re

ft_printf.h

#ifndef FT_PRINTF_H
# define FT_PRINTF_H

# include "./libft/libft.h"
# include <limits.h>
# include <stdarg.h>
# include <stdlib.h>
# include <unistd.h>

# define HEX_CHARS_LOWER "0123456789abcdef"
# define HEX_CHARS_UPPER "0123456789ABCDEF"
# define HANDLE_ERROR(condition, action) \
	if (condition)                      \
	{                                   \
		action;                         \
	}

int		ft_printf(const char *bs, ...);

int		c_func(va_list ap);
int		s_func(va_list ap);
int		s_func(va_list ap);
int		p_func(va_list ap);
int		d_func(va_list ap);
int		u_func(va_list ap);
int		sx_func(va_list ap);
int		lx_func(va_list ap);

char	*ft_itoahex(unsigned long long n, const char *hex);

#endif
โš ๏ธ **GitHub.com Fallback** โš ๏ธ