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
%.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