diff --git a/Makefile b/Makefile index 0f2ead2..d9e336a 100644 --- a/Makefile +++ b/Makefile @@ -25,6 +25,10 @@ B_SRC= $(B_SRC_DIR)/ft_printf_bonus.c \ $(B_SRC_DIR)/print_pointer_bonus.c \ $(B_SRC_DIR)/print_str_bonus.c \ $(B_SRC_DIR)/print_unsigned_bonus.c \ + $(B_SRC_DIR)/ft_create_arg_bonus.c \ + $(B_SRC_DIR)/ft_main_arg_bonus.c \ + $(B_SRC_DIR)/ft_parsing_bonus.c \ + $(B_SRC_DIR)/utils_flag_bonus.c OBJ= $(SRC:%.c=$(BUILD_DIR)/%.o) diff --git a/bonus/ft_create_arg_bonus.c b/bonus/ft_create_arg_bonus.c new file mode 100644 index 0000000..24920e4 --- /dev/null +++ b/bonus/ft_create_arg_bonus.c @@ -0,0 +1,30 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_create_arg_bonus.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: dgaillet +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/11/19 15:52:18 by dgaillet #+# #+# */ +/* Updated: 2025/11/19 18:29:53 by dgaillet ### ########lyon.fr */ +/* */ +/* ************************************************************************** */ + +#include +#include "ft_printf_bonus.h" + +t_arg *ft_create_arg(void) +{ + t_arg *arg; + + arg = malloc(sizeof(t_arg)); + if (!arg) + return (NULL); + arg->minus = 0; + arg->zero = 0; + arg->dot = 0; + arg->hash = 0; + arg->space = 0; + arg->plus = 0; + return (arg); +} diff --git a/bonus/ft_main_arg_bonus.c b/bonus/ft_main_arg_bonus.c new file mode 100644 index 0000000..1d834b5 --- /dev/null +++ b/bonus/ft_main_arg_bonus.c @@ -0,0 +1,30 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_main_arg.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: dgaillet +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/11/19 15:38:58 by dgaillet #+# #+# */ +/* Updated: 2025/11/19 15:45:26 by dgaillet ### ########lyon.fr */ +/* */ +/* ************************************************************************** */ + +static int is_main_arg(char c) +{ + if (c == 'c' || c == 's' || c == 'p' || c == 'd' + || c == 'i' || c == 'u' || c == 'x' || c == 'X' || c == '%') + return (1); + return (0); +} + +char ft_main_arg(char *str) +{ + while (*str) + { + if (is_main_arg(*str)) + break ; + str++; + } + return (*str); +} diff --git a/bonus/ft_parsing_bonus.c b/bonus/ft_parsing_bonus.c new file mode 100644 index 0000000..c970100 --- /dev/null +++ b/bonus/ft_parsing_bonus.c @@ -0,0 +1,64 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_parsing_bonus.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: dgaillet +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/11/19 15:35:15 by dgaillet #+# #+# */ +/* Updated: 2025/11/19 19:09:25 by dgaillet ### ########lyon.fr */ +/* */ +/* ************************************************************************** */ + +#include "ft_printf_bonus.h" +#include "libft.h" + +static int next_not_digit(char *str) +{ + int i; + + i = 0; + while (ft_isdigit(str[i])) + i++; + return (i); +} + +static int nb_to_skip(char *str) +{ + if (*str == '-') + return (1 + next_not_digit(&str[1])); + else if (*str == '0') + return (1 + next_not_digit(&str[1])); + else if (*str == '.') + return (1 + next_not_digit(&str[1])); + return (1); +} + +t_arg *ft_parsing(char *str) +{ + t_arg *arg; + char main_arg; + + main_arg = ft_main_arg(str); + arg = ft_create_arg(); + if (!arg) + return (0); + arg->arg = main_arg; + while (*str != main_arg) + { + if (*str == '-') + arg->minus = ft_atoi(&str[1]); + else if (*str == '0') + arg->zero = ft_atoi(&str[1]); + else if (*str == '.') + arg->dot = ft_atoi(&str[1]); + else if (*str == '#') + arg->hash = 1; + else if (*str == ' ') + arg->space = 1; + else if (*str == '+') + arg->zero = 1; + str += nb_to_skip(str); + } + return (arg); +} diff --git a/bonus/ft_printf_bonus.c b/bonus/ft_printf_bonus.c index 3df5400..a5619a7 100644 --- a/bonus/ft_printf_bonus.c +++ b/bonus/ft_printf_bonus.c @@ -6,33 +6,65 @@ /* By: dgaillet +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/11/17 10:54:03 by dgaillet #+# #+# */ -/* Updated: 2025/11/19 13:35:28 by dgaillet ### ########lyon.fr */ +/* Updated: 2025/11/19 20:50:02 by dgaillet ### ########lyon.fr */ /* */ /* ************************************************************************** */ #include #include #include "ft_printf_bonus.h" +#include -static int ft_print_arg(char c, va_list args) +static int ft_print_arg_flags(t_arg *arg, va_list args) { - if (c == 'c') - return (print_char(va_arg(args, int))); - else if (c == 's') - return (print_str(va_arg(args, char *))); - else if (c == 'p') - return (print_pointer(va_arg(args, unsigned long long))); - else if (c == 'd' || c == 'i') - return (print_number(va_arg(args, int))); - else if (c == 'u') - return (print_unsigned(va_arg(args, unsigned int))); - else if (c == 'x') - return (print_hex(va_arg(args, unsigned int), 0)); - else if (c == 'X') - return (print_hex(va_arg(args, unsigned int), 1)); - else if (c == '%') - return (print_char('%')); - return (0); + int count; + + count = 0; + if (arg->arg == 'c') + count += print_char(arg, va_arg(args, int)); + else if (arg->arg == 's') + count += print_str(arg, va_arg(args, char *)); + else if (arg->arg == 'p') + count += print_pointer(arg, va_arg(args, unsigned long long)); + else if (arg->arg == 'd' || arg->arg == 'i') + count += print_number(arg, va_arg(args, int)); + else if (arg->arg == 'u') + count += print_unsigned(arg, va_arg(args, unsigned long)); + else if (arg->arg == 'x' || arg->arg == 'X') + count += print_hex(arg, va_arg(args, unsigned int)); + count += print_chars(arg->minus - count, ' '); + return (count); +} + +static int ft_print_arg(char *str, va_list args) +{ + t_arg *arg; + int count; + + arg = ft_parsing(str); + if (!arg) + return (0); + if (arg->arg == '%') + count = write(1, "%", 1); + else + count = ft_print_arg_flags(arg, args); + free(arg); + return (count); +} + +static int ft_to_skip(char *str) +{ + int count; + + count = 0; + while (!(*str == 'c' || *str == 's' || *str == 'p' || *str == 'd' + || *str == 'i' || *str == 'u' || *str == 'x' || *str == 'X' + || *str == '%') && *str) + { + count++; + str++; + } + return (count); } int ft_printf(const char *first_arg, ...) @@ -49,11 +81,13 @@ int ft_printf(const char *first_arg, ...) if (first_arg[i] == '%') { i++; - nb_print += ft_print_arg(first_arg[i], args); + nb_print += ft_print_arg((char *) &first_arg[i], args); + i += ft_to_skip((char *) &first_arg[i]); } else nb_print += write(1, &first_arg[i], 1); i++; } + va_end(args); return (nb_print); } diff --git a/bonus/print_char_bonus.c b/bonus/print_char_bonus.c index 70d8ec3..325d2de 100644 --- a/bonus/print_char_bonus.c +++ b/bonus/print_char_bonus.c @@ -1,18 +1,26 @@ /* ************************************************************************** */ /* */ /* ::: :::::::: */ -/* print_char.c :+: :+: :+: */ +/* print_char_bonus.c :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: dgaillet +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/11/17 11:56:36 by dgaillet #+# #+# */ -/* Updated: 2025/11/17 12:45:57 by dgaillet ### ########lyon.fr */ +/* Updated: 2025/11/19 19:42:20 by dgaillet ### ########lyon.fr */ /* */ /* ************************************************************************** */ +#include "ft_printf_bonus.h" #include +#include -int print_char(char c) +int print_char(t_arg *arg, char c) { - return (write(1, &c, 1)); + int count; + + count = 0; + if (!arg->minus && arg->zero) + count += print_chars(arg->zero - 1, ' '); + count += write(1, &c, 1); + return (count); } diff --git a/bonus/print_hex_bonus.c b/bonus/print_hex_bonus.c index 3517be2..7489b33 100644 --- a/bonus/print_hex_bonus.c +++ b/bonus/print_hex_bonus.c @@ -6,19 +6,31 @@ /* By: dgaillet +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/11/17 12:06:35 by dgaillet #+# #+# */ -/* Updated: 2025/11/19 13:35:40 by dgaillet ### ########lyon.fr */ +/* Updated: 2025/11/19 20:14:08 by dgaillet ### ########lyon.fr */ /* */ /* ************************************************************************** */ #include "ft_printf_bonus.h" #include -int print_hex(unsigned long long nbr, int upper) +int print_hex(t_arg *arg, unsigned long long nbr) { + int count; + + count = 0; if (nbr == 0) - return (write(1, "0", 1)); - if (upper) - return (ft_putnbr_base(nbr, "0123456789ABCDEF", 16)); + count += write(1, "0", 1); else - return (ft_putnbr_base(nbr, "0123456789abcdef", 16)); + { + if (arg->hash && arg->arg == 'X') + count += write(1, "0X", 2); + else if (arg->hash) + count += write(1, "0x", 2); + count += print_chars(arg->zero - count - nbr_size_base(nbr, 16), '0'); + if (arg->arg == 'X') + count += ft_putnbr_base(nbr, "0123456789ABCDEF", 16); + else + count += ft_putnbr_base(nbr, "0123456789abcdef", 16); + } + return (count); } diff --git a/bonus/print_number_bonus.c b/bonus/print_number_bonus.c index ec86c71..c8a2941 100644 --- a/bonus/print_number_bonus.c +++ b/bonus/print_number_bonus.c @@ -6,24 +6,29 @@ /* By: dgaillet +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/11/17 12:26:23 by dgaillet #+# #+# */ -/* Updated: 2025/11/19 13:35:48 by dgaillet ### ########lyon.fr */ +/* Updated: 2025/11/19 19:56:04 by dgaillet ### ########lyon.fr */ /* */ /* ************************************************************************** */ #include "ft_printf_bonus.h" #include -int print_number(int nbr) +int print_number(t_arg *arg, int nbr) { unsigned int p_nbr; + int count; + count = 0; + p_nbr = nbr; if (nbr == 0) - return (write(1, "0", 1)); + count += write(1, "0", 1); if (nbr < 0) { - write(1, "-", 1); + count += write(1, "-", 1); p_nbr = nbr * -1; - return (1 + ft_putnbr_base(p_nbr, "0123456789", 10)); + count += print_chars(arg->zero - nbr_size_base(p_nbr, 10) - 1, '0'); } - return (ft_putnbr_base(nbr, "0123456789", 10)); + else + count += print_chars(arg->zero - nbr_size_base(p_nbr, 10), '0'); + return (count + ft_putnbr_base(p_nbr, "0123456789", 10)); } diff --git a/bonus/print_pointer_bonus.c b/bonus/print_pointer_bonus.c index ab27edc..1340836 100644 --- a/bonus/print_pointer_bonus.c +++ b/bonus/print_pointer_bonus.c @@ -6,20 +6,25 @@ /* By: dgaillet +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/11/17 12:19:16 by dgaillet #+# #+# */ -/* Updated: 2025/11/19 13:35:58 by dgaillet ### ########lyon.fr */ +/* Updated: 2025/11/19 20:16:31 by dgaillet ### ########lyon.fr */ /* */ /* ************************************************************************** */ #include "libft.h" #include "ft_printf_bonus.h" -int print_pointer(unsigned long long p) +int print_pointer(t_arg *arg, unsigned long long p) { + int count; + + count = 0; if (!p) { ft_putstr_fd("(nil)", 1); return (5); } - ft_putstr_fd("0x", 1); - return (2 + ft_putnbr_base(p, "0123456789abcdef", 16)); + if (arg->arg) + ft_putstr_fd("", 1); + count += write(1, "0x", 2); + return (count + ft_putnbr_base(p, "0123456789abcdef", 16)); } diff --git a/bonus/print_str_bonus.c b/bonus/print_str_bonus.c index ae7726c..5d89b18 100644 --- a/bonus/print_str_bonus.c +++ b/bonus/print_str_bonus.c @@ -1,24 +1,27 @@ /* ************************************************************************** */ /* */ /* ::: :::::::: */ -/* print_str.c :+: :+: :+: */ +/* print_str_bonus.c :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: dgaillet +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/11/17 12:02:03 by dgaillet #+# #+# */ -/* Updated: 2025/11/17 12:51:56 by dgaillet ### ########lyon.fr */ +/* Updated: 2025/11/19 20:16:48 by dgaillet ### ########lyon.fr */ /* */ /* ************************************************************************** */ #include "libft.h" +#include "ft_printf_bonus.h" -int print_str(char *str) +int print_str(t_arg *arg, char *str) { if (!str) { ft_putstr_fd("(null)", 1); return (6); } + if (arg->arg) + ft_putstr_fd("", 1); ft_putstr_fd(str, 1); return (ft_strlen(str)); } diff --git a/bonus/print_unsigned_bonus.c b/bonus/print_unsigned_bonus.c index 259a7e6..2c3e559 100644 --- a/bonus/print_unsigned_bonus.c +++ b/bonus/print_unsigned_bonus.c @@ -6,16 +6,21 @@ /* By: dgaillet +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/11/17 12:26:23 by dgaillet #+# #+# */ -/* Updated: 2025/11/19 13:36:08 by dgaillet ### ########lyon.fr */ +/* Updated: 2025/11/19 20:56:30 by dgaillet ### ########lyon.fr */ /* */ /* ************************************************************************** */ #include "ft_printf_bonus.h" #include -int print_unsigned(unsigned int nbr) +int print_unsigned(t_arg *arg, unsigned long nbr) { + int count; + + count = 0; if (nbr == 0) - return (write(1, "0", 1)); - return (ft_putnbr_base(nbr, "0123456789", 10)); + count += write(1, "0", 1); + count += print_chars(arg->zero - nbr_size_base(nbr, 10), '0'); + count += ft_putnbr_base(nbr, "0123456789", 10); + return (count); } diff --git a/bonus/utils_flag_bonus.c b/bonus/utils_flag_bonus.c new file mode 100644 index 0000000..2e03506 --- /dev/null +++ b/bonus/utils_flag_bonus.c @@ -0,0 +1,42 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* utils_flag_bonus.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: dgaillet +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/11/19 17:07:22 by dgaillet #+# #+# */ +/* Updated: 2025/11/19 19:53:38 by dgaillet ### ########lyon.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" +#include + +int nbr_size_base(unsigned long long nb, int base_size) +{ + int count; + + count = 0; + if (nb == 0) + return (1); + while (nb) + { + count++; + nb /= base_size; + } + return (count); +} + +int print_chars(int nb, char c) +{ + int count; + + count = 0; + while (nb > 0) + { + count += write(1, &c, 1); + nb--; + } + return (count); +} diff --git a/include/ft_printf_bonus.h b/include/ft_printf_bonus.h index 1c48920..7634610 100644 --- a/include/ft_printf_bonus.h +++ b/include/ft_printf_bonus.h @@ -6,7 +6,7 @@ /* By: dgaillet +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/11/17 10:52:23 by dgaillet #+# #+# */ -/* Updated: 2025/11/19 13:30:52 by dgaillet ### ########lyon.fr */ +/* Updated: 2025/11/19 20:48:36 by dgaillet ### ########lyon.fr */ /* */ /* ************************************************************************** */ @@ -24,15 +24,20 @@ typedef struct s_arg int plus; } t_arg; -int ft_printf(const char *first_arg, ...); +int ft_printf(const char *first_arg, ...); -int ft_putnbr_base(unsigned long long nbr, char *base, int base_size); +int ft_putnbr_base(unsigned long long nbr, char *base, int base_size); +char ft_main_arg(char *str); +t_arg *ft_create_arg(void); +t_arg *ft_parsing(char *str); +int print_chars(int nb, char c); +int nbr_size_base(unsigned long long nb, int base_size); -int print_char(char c); -int print_str(char *str); -int print_pointer(unsigned long long p); -int print_number(int nbr); -int print_unsigned(unsigned int nbr); -int print_hex(unsigned long long p, int upper); +int print_char(t_arg *arg, char c); +int print_str(t_arg *arg, char *str); +int print_pointer(t_arg *arg, unsigned long long p); +int print_number(t_arg *arg, int nbr); +int print_unsigned(t_arg *arg, unsigned long nbr); +int print_hex(t_arg *arg, unsigned long long p); #endif diff --git a/src/ft_printf.c b/src/ft_printf.c index 2a3b6d3..9cb1f33 100644 --- a/src/ft_printf.c +++ b/src/ft_printf.c @@ -6,7 +6,7 @@ /* By: dgaillet +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/11/17 10:54:03 by dgaillet #+# #+# */ -/* Updated: 2025/11/17 12:47:03 by dgaillet ### ########lyon.fr */ +/* Updated: 2025/11/19 17:52:14 by dgaillet ### ########lyon.fr */ /* */ /* ************************************************************************** */ @@ -55,5 +55,6 @@ int ft_printf(const char *first_arg, ...) nb_print += write(1, &first_arg[i], 1); i++; } + va_end(args); return (nb_print); } diff --git a/test.c b/test.c new file mode 100644 index 0000000..fdd2641 --- /dev/null +++ b/test.c @@ -0,0 +1,12 @@ +#include +#include "ft_printf_bonus.h" + +int main(void) +{ + printf("===\t-\t===\n\n"); + printf("%d - ", printf("...%#x...\n", 1358454)); + printf("%d\n\n", ft_printf("...%#x...\n", 1358454)); + + printf("%d - ", printf("...%-1u...\n", 0)); + printf("%d\n\n", ft_printf("...%-1u...\n", 0)); +}