From: Lukas Jiriste Date: Sat, 26 Aug 2023 05:59:25 +0000 (+0200) Subject: ft_print.c now conforms to the Norm (except function number). X-Git-Url: https://git.ljiriste.work/?a=commitdiff_plain;h=1bc84f39ee38d26ec53f7aaab038f531453b2ff2;p=42%2Fft_printf.git ft_print.c now conforms to the Norm (except function number). Not all functionality is yet provided (notably %%, other need to be found by testing). New version of Libft is used. --- diff --git a/Libft b/Libft index 176dfd9..5b3c0fc 160000 --- a/Libft +++ b/Libft @@ -1 +1 @@ -Subproject commit 176dfd9fd936e853cf87239219416ee774602dcf +Subproject commit 5b3c0fcbf58c6458fcd10d2ad48c9f698ce7a8c8 diff --git a/ft_printf.c b/ft_printf.c index 9946fb0..ef106de 100644 --- a/ft_printf.c +++ b/ft_printf.c @@ -10,8 +10,8 @@ /* */ /* ************************************************************************** */ -#include // malloc, free -#include // va_* +#include // malloc, free +#include // va_* #include // write #include "libft.h" @@ -27,7 +27,7 @@ int print_ordinary(const char **s) return (len); } -typedef struct s_flags +typedef struct s_flags { int alt_mode; int zero_pad; @@ -36,7 +36,7 @@ typedef struct s_flags int sign_show; } t_flags; -typedef struct s_conv +typedef struct s_conv { t_flags flags; int minwidth; @@ -52,7 +52,7 @@ t_flags parse_flags(const char **format) flags.zero_pad = 0; flags.left_adjust = 0; flags.sign_allign = 0; - flags.sign_show = 0; + flags.sign_show = 0; while (1) { if (**format == '#') @@ -128,11 +128,18 @@ int valid_base(const char *base) return (1); } +intptr_t ft_abs(intptr_t n) +{ + if (n < 0) + return (-n); + else + return (n); +} char *ft_itoa_base(intptr_t n, const char *base) { int size; - size_t base_len; + int base_len; char *res; if (!valid_base(base)) @@ -147,7 +154,7 @@ char *ft_itoa_base(intptr_t n, const char *base) res[size--] = '\0'; while (n != 0) { - res[size--] = base[abs(n % base_len)]; + res[size--] = base[ft_abs(n % base_len)]; n /= base_len; } return (res); @@ -206,7 +213,7 @@ t_conv parse_format(const char **format, va_list *args) return (conv); } -typedef struct s_printed +typedef struct s_to_print { char *left_pad; char sign; @@ -214,13 +221,13 @@ typedef struct s_printed char *zero_pad; char *main_part; char *right_pad; -} t_printed; +} t_to_print; char *create_alt(t_conv conv) { if (conv.type == 'p') return (ft_strdup("0x")); - else if (conv.flag.alt_mode) + else if (conv.flags.alt_mode) { if (conv.type == 'o') return (ft_strdup("0")); @@ -234,7 +241,7 @@ char *create_alt(t_conv conv) void create_main(char *str, t_conv conv, t_to_print *tp) { - if (conv.type == 'd' || conv.type == 'i') + if (conv.type == 'd' || conv.type == 'i') { if (*str == '-') { @@ -243,40 +250,129 @@ void create_main(char *str, t_conv conv, t_to_print *tp) } else { - tp->main_part = ft_strfup(str); + tp->main_part = ft_strdup(str); if (conv.flags.sign_show) tp->sign = '+'; else if (conv.flags.sign_allign) tp->sign = ' '; } } - else if (conv.type == 's' && conv.prec < ft_strlen(str)) + else if (conv.type == 's' + && (size_t)conv.prec < ft_strlen(str) && conv.prec >= 0) + tp->main_part = ft_strndup(str, conv.prec); + else + tp->main_part = ft_strdup(str); + return ; +} + +void init_printed(t_to_print *tp) +{ + tp->left_pad = NULL; + tp->sign = '\0'; + tp->zero_pad = NULL; + tp->main_part = NULL; + tp->right_pad = NULL; + return ; +} + +char *rep_char(char c, int n) +{ + char *res; + + if (n < 0) + n = 0; + res = malloc(++n); + if (res == NULL) + return (res); + res[--n] = '\0'; + while (n > 0) + res[--n] = c; + return (res); +} + +void lengthen_by_zeros(char **str, int n) +{ + char *temp; + size_t size; + + if (n <= 0) + return ; + temp = *str; + size = ft_strlen(temp) + n + 1; + *str = malloc(size); + if (*str == NULL) { - tp->main_part = malloc((conv.prec + 1) * sizeof(char)); - if (tp.main_part == NULL) - return (); - ft_strlcpy(tp->main_part, str, conv.prec + 1); + free(temp); + return ; + } + ft_strlcpy(*str, temp, size); + free(temp); + while (n > 0) + (*str)[size - (n--) - 1] = '0'; + (*str)[size - 1] = '\0'; + return ; +} + +void create_padding(t_to_print *tp, t_conv conv) +{ + size_t len; + + len = ft_strlen(tp->main_part); + tp->zero_pad = rep_char('0', conv.prec - len); + len += ft_strlen(tp->zero_pad) + ft_strlen(tp->alt) + (tp->sign != '\0'); + if (conv.flags.left_adjust) + { + tp->right_pad = rep_char(' ', conv.minwidth - len); + tp->left_pad = ft_strdup(""); } else - tp->main_part = ft_strdup(str); - return (); + { + tp->right_pad = ft_strdup(""); + if (!conv.flags.zero_pad || conv.type == 's') + tp->left_pad = rep_char(' ', conv.minwidth - len); + else if (conv.flags.zero_pad) + { + tp->left_pad = ft_strdup(""); + lengthen_by_zeros(&(tp->zero_pad), conv.minwidth - len); + } + } + return ; } -t_printed formated(char *str, t_conv conv) +t_to_print formated(char *str, t_conv conv) { t_to_print res; init_printed(&res); create_main(str, conv, &res); res.alt = create_alt(conv); - + create_padding(&res, conv); + return (res); +} + +int valid_toprint(t_to_print tp) +{ + return (tp.left_pad && tp.zero_pad && tp.main_part && tp.right_pad); +} + +size_t to_print_len(t_to_print tp) +{ + size_t len; + + len = 0; + len += ft_strlen(tp.left_pad); + len += (tp.sign != '\0'); + len += ft_strlen(tp.alt); + len += ft_strlen(tp.zero_pad); + len += ft_strlen(tp.main_part); + len += ft_strlen(tp.right_pad); + return (len); } int handle_conversion(const char **format, va_list *args) { t_conv conv; - char *str; - int len; + char *temp; t_to_print to_print; ++(*format); @@ -292,7 +388,7 @@ int handle_conversion(const char **format, va_list *args) ft_putstr_fd(to_print.alt, 1); ft_putstr_fd(to_print.main_part, 1); ft_putstr_fd(to_print.right_pad, 1); - return (len); + return (to_print_len(to_print)); } int ft_printf(const char *format, ...) @@ -300,12 +396,13 @@ int ft_printf(const char *format, ...) va_list args; int res; + res = 0; va_start(args, format); while (*format) { res += print_ordinary(&format); if (!*format) - break; + break ; res += handle_conversion(&format, &args); } va_end(args);