function printf a la norme
This commit is contained in:
3
Makefile
3
Makefile
@@ -16,9 +16,8 @@ LIBS = $(_LIBS:lib%.a=%)
|
|||||||
|
|
||||||
SRCS = ft_printf.c \
|
SRCS = ft_printf.c \
|
||||||
ft_next_word.c \
|
ft_next_word.c \
|
||||||
aside.c \
|
|
||||||
ft_convert.c \
|
ft_convert.c \
|
||||||
ft_width_n_precision.c \
|
ft_flag_transform.c \
|
||||||
main.c
|
main.c
|
||||||
|
|
||||||
ODIR = ./builds
|
ODIR = ./builds
|
||||||
|
|||||||
183
ft_printf.c
183
ft_printf.c
@@ -1,70 +1,131 @@
|
|||||||
|
/* ************************************************************************** */
|
||||||
|
/* */
|
||||||
|
/* ::: :::::::: */
|
||||||
|
/* ft_printf.c :+: :+: :+: */
|
||||||
|
/* +:+ +:+ +:+ */
|
||||||
|
/* By: hulamy <marvin@42.fr> +#+ +:+ +#+ */
|
||||||
|
/* +#+#+#+#+#+ +#+ */
|
||||||
|
/* Created: 2020/02/27 12:01:26 by hulamy #+# #+# */
|
||||||
|
/* Updated: 2020/02/27 12:01:30 by hulamy ### ########.fr */
|
||||||
|
/* */
|
||||||
|
/* ************************************************************************** */
|
||||||
|
|
||||||
#include "ft_printf.h"
|
#include "ft_printf.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** FT_FLAG_TRANSFORM :
|
** SPECIFIER :
|
||||||
** if i = flag_p(&s) | -precision is calculated before width,
|
** receive a word as a string, check if it start by '%', and return the
|
||||||
** | on str, if < length(str), cuts it,
|
** specifier (diuxXspefgn) and the length (h hh l ll)
|
||||||
** print = ft_precision() | on nbr, if > length(nbr), add '0' before,
|
** -if s is a string, or is a single '%'
|
||||||
** | then add '-' if negatif
|
** return NULL (to print is as a string)
|
||||||
** | (if precision given with flag '0', it's
|
** -if s is a double '%%', remove one '%', and
|
||||||
** | ignored and cuted from s)
|
** return NULL (to print is as a string)
|
||||||
** if i = flag_w(s) | -width is caculated
|
** -then s is a conversion, go to the length and specifier
|
||||||
** if flag_-(&s) | -if flag '-', rm '-' and width from s
|
** -copy them in 'string'
|
||||||
** print = ft_rpadd() | -put extra width as ' ' to right,
|
** -and remove them from s
|
||||||
** else if flag_0(&s) | -if flag '0', rm '0' and width from s
|
** -return the length and specifier in a string
|
||||||
** print = ft_lpadd() | -put extra width as '0' to left
|
|
||||||
** else | -if just width
|
|
||||||
** print = ft_lpadd() | put extra width as ' ' to left
|
|
||||||
** // if flag_+(s) |
|
|
||||||
** // else if flag_space(s) |
|
|
||||||
** // if flag_'(s) |
|
|
||||||
** // if flag_#(s) |
|
|
||||||
** // print = ft_altfrm() |
|
|
||||||
**
|
|
||||||
** int flag_p(char **s);
|
|
||||||
** char *ft_precision(int i, char *print);
|
|
||||||
** int flag_w(char *s);
|
|
||||||
** void flag_-(char **s);
|
|
||||||
** char *ft_rpadd(int i, char *print);
|
|
||||||
** char *ft_lpadd(int i, char *print, char c);
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
char *ft_flag_transform(char *s, char *print, char *type)
|
char *specifier(char *s)
|
||||||
{
|
{
|
||||||
print = ft_precision(s, print, type);
|
char *string;
|
||||||
print = ft_width(s, print);
|
int i;
|
||||||
|
|
||||||
// if (flag_+(s)) //
|
if (s[0] != '%' || s[1] == '\0')
|
||||||
// else if (flag_space(s)) //
|
return (NULL);
|
||||||
// if (flag_'(s)) //
|
if (s[1] == '%')
|
||||||
// if (flag_#(s)) //
|
{
|
||||||
// print = ft_alternate_form(print) //
|
s[1] = '\0';
|
||||||
return (print);
|
return (NULL);
|
||||||
|
}
|
||||||
|
i = 1;
|
||||||
|
while (ft_strchr("#0- +'0123456789.*", s[i]) != NULL)
|
||||||
|
i++;
|
||||||
|
string = ft_strdup(s + i);
|
||||||
|
while (s[i] != '\0')
|
||||||
|
{
|
||||||
|
s[i] = '\0';
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
return (string);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** FT_PRINTF :
|
** -receive 'i' the number in which '*' will expand
|
||||||
** va_list ap;
|
** -turn it into a string
|
||||||
** int length;
|
** -calculate the total lentgh of the string '%...' for nbr replacing '*'
|
||||||
** char *print; | -contain the arg converted into a string
|
** -allocate a new string with this length
|
||||||
** char *type; | -contain the specifier type to use
|
** -copy the original str with first '*' expanded into it's corresponding nbr
|
||||||
** | by va_arg
|
*/
|
||||||
** while s = next_word() | -return the next sequence to be print
|
|
||||||
** | (either a string, or a conversion)
|
int ft_expand_star(int nbr, char **string)
|
||||||
** type = specifier(s) | -return the type if it's a conversion, or "%",
|
{
|
||||||
** | or NULL if it's a string. if it's a
|
char *s;
|
||||||
** | single '%' it's considered as a string
|
char *n;
|
||||||
** | if convers0, rmvs length & specifier from s
|
int i;
|
||||||
** if !type: ft_put_word() | -print the string if it wasn't a conversion
|
int j;
|
||||||
** else | or if it was a '%%'
|
int k;
|
||||||
** while strchr(s,*) | -for each * present, expand it into s in
|
|
||||||
** ft_expand_star()| order it appears
|
n = ft_itoa(nbr);
|
||||||
** print = ft_convert()| -convert the arg with its type,
|
if (!(s = ft_memalloc(sizeof(char) * (ft_strlen(n) + ft_strlen(*string)))))
|
||||||
** | then trsfm it into a str and rtrn the str
|
return (0);
|
||||||
** ft_flag_transform() | -proceed all modification according to flags
|
i = -1;
|
||||||
** ft_put_word(print) | -print the string fully converted
|
j = 0;
|
||||||
** return (length) | -return the length of what was printed
|
k = 0;
|
||||||
|
while ((*string)[++i] != '\0')
|
||||||
|
{
|
||||||
|
s[j] = (*string)[i];
|
||||||
|
if (s[j] == '*')
|
||||||
|
while (n[k] != '\0')
|
||||||
|
s[j++] = n[k++];
|
||||||
|
else
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
free(n);
|
||||||
|
free(*string);
|
||||||
|
*string = s;
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** print the string
|
||||||
|
** because of lake of space, it also free 'type'
|
||||||
|
*/
|
||||||
|
|
||||||
|
int ft_put_word(char *s, char *type)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
free(type);
|
||||||
|
i = ft_strlen(s);
|
||||||
|
ft_putstr(s);
|
||||||
|
free(s);
|
||||||
|
return (i);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** print the string
|
||||||
|
** because of lake of space, it also free 'type'
|
||||||
|
*/
|
||||||
|
|
||||||
|
int length_n_free(int length, char *s)
|
||||||
|
{
|
||||||
|
free(s);
|
||||||
|
return (length);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** -printf receive a string to print with a variadic number of arguments
|
||||||
|
** -it will go in a loop through each 'words'
|
||||||
|
** -a word is either a string containing no '%' or a conversion starting by '%'
|
||||||
|
** -if it's a string it's printed right away
|
||||||
|
** -if it's a conversion it will go through some actions :
|
||||||
|
** -1 expand all the stars from width and .precision
|
||||||
|
** they always expand into int type
|
||||||
|
** it's done first because those are the first next args on the va_list
|
||||||
|
** -2 expand the specifier according to its type and its length
|
||||||
|
** and put in a string 'print'
|
||||||
|
** -3 transform 'print' according to the flags
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int ft_printf(char *string, ...)
|
int ft_printf(char *string, ...)
|
||||||
@@ -80,7 +141,7 @@ int ft_printf(char *string, ...)
|
|||||||
while ((s = next_word(&string)) != NULL)
|
while ((s = next_word(&string)) != NULL)
|
||||||
{
|
{
|
||||||
if ((type = specifier(s)) == NULL)
|
if ((type = specifier(s)) == NULL)
|
||||||
length += ft_put_word(s);
|
length += ft_put_word(s, type);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
while (ft_strchr(s, '*'))
|
while (ft_strchr(s, '*'))
|
||||||
@@ -90,12 +151,8 @@ int ft_printf(char *string, ...)
|
|||||||
return (-1);
|
return (-1);
|
||||||
if (!(print = ft_flag_transform(s, print, type)))
|
if (!(print = ft_flag_transform(s, print, type)))
|
||||||
return (-1);
|
return (-1);
|
||||||
length += ft_put_word(print);
|
length += ft_put_word(print, type);
|
||||||
free(print);
|
|
||||||
}
|
}
|
||||||
free(s);
|
|
||||||
free(type);
|
|
||||||
}
|
}
|
||||||
free(s);
|
return (length_n_free(length, s));
|
||||||
return (length);
|
|
||||||
}
|
}
|
||||||
|
|||||||
13
ft_printf.h
13
ft_printf.h
@@ -8,7 +8,10 @@
|
|||||||
# include <stdio.h>
|
# include <stdio.h>
|
||||||
|
|
||||||
// ft_printf.c
|
// ft_printf.c
|
||||||
char *ft_flag_transform(char *s, char *print, char *type);
|
char *specifier(char *s);
|
||||||
|
int ft_expand_star(int nbr, char **string);
|
||||||
|
int ft_put_word(char *s, char *type);
|
||||||
|
int length_n_free(int length, char *s);
|
||||||
int ft_printf(char *string, ...);
|
int ft_printf(char *string, ...);
|
||||||
|
|
||||||
// ft_next_word.c
|
// ft_next_word.c
|
||||||
@@ -16,20 +19,16 @@ int width_precision(char *s);
|
|||||||
int word_length(char *s);
|
int word_length(char *s);
|
||||||
char *next_word(char **s);
|
char *next_word(char **s);
|
||||||
|
|
||||||
// aside.c
|
|
||||||
char *specifier(char *s);
|
|
||||||
int ft_put_word(char *s);
|
|
||||||
int ft_expand_star(int nbr, char **string);
|
|
||||||
|
|
||||||
// ft_convert.c
|
// ft_convert.c
|
||||||
char *conv_i(char c, long int i);
|
char *conv_i(char c, long int i);
|
||||||
char *conv_u(char c, unsigned long int i);
|
char *conv_u(char c, unsigned long int i);
|
||||||
char *ft_convert(va_list ap, char *type);
|
char *ft_convert(va_list ap, char *type);
|
||||||
|
|
||||||
// ft_width_n_precision.c
|
// ft_flag_transform.c
|
||||||
char *precision_int(char *print, int precision);
|
char *precision_int(char *print, int precision);
|
||||||
char *ft_precision(char *s, char *print, char *type);
|
char *ft_precision(char *s, char *print, char *type);
|
||||||
char *width_flags(char *print, char *tmp, char *s, int width);
|
char *width_flags(char *print, char *tmp, char *s, int width);
|
||||||
char *ft_width(char *s, char *print);
|
char *ft_width(char *s, char *print);
|
||||||
|
char *ft_flag_transform(char *s, char *print, char *type);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
101
srcs/aside.c
101
srcs/aside.c
@@ -1,101 +0,0 @@
|
|||||||
/* ************************************************************************** */
|
|
||||||
/* */
|
|
||||||
/* ::: :::::::: */
|
|
||||||
/* aside.c :+: :+: :+: */
|
|
||||||
/* +:+ +:+ +:+ */
|
|
||||||
/* By: hulamy <marvin@42.fr> +#+ +:+ +#+ */
|
|
||||||
/* +#+#+#+#+#+ +#+ */
|
|
||||||
/* Created: 2020/02/19 16:23:01 by hulamy #+# #+# */
|
|
||||||
/* Updated: 2020/02/26 17:43:21 by hulamy ### ########.fr */
|
|
||||||
/* */
|
|
||||||
/* ************************************************************************** */
|
|
||||||
|
|
||||||
#include "ft_printf.h"
|
|
||||||
|
|
||||||
/*
|
|
||||||
** SPECIFIER :
|
|
||||||
** receive a word as a string, check if it start by '%', and return the
|
|
||||||
** specifier (diuxXspefgn) and the length (h hh l ll)
|
|
||||||
** -if s is a string, or is a single '%'
|
|
||||||
** return NULL (to print is as a string)
|
|
||||||
** -if s is a double '%%', remove one '%', and
|
|
||||||
** return NULL (to print is as a string)
|
|
||||||
** -then s is a conversion, go to the length and specifier
|
|
||||||
** -copy them in 'string'
|
|
||||||
** -and remove them from s
|
|
||||||
** -return the length and specifier in a string
|
|
||||||
*/
|
|
||||||
|
|
||||||
char *specifier(char *s)
|
|
||||||
{
|
|
||||||
char *string;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
if (s[0] != '%' || s[1] == '\0')
|
|
||||||
return (NULL);
|
|
||||||
if (s[1] == '%')
|
|
||||||
{
|
|
||||||
s[1] = '\0';
|
|
||||||
return (NULL);
|
|
||||||
}
|
|
||||||
i = 1;
|
|
||||||
while (ft_strchr("#0- +'0123456789.*", s[i]) != NULL)
|
|
||||||
i++;
|
|
||||||
string = ft_strdup(s + i);
|
|
||||||
while (s[i] != '\0')
|
|
||||||
{
|
|
||||||
s[i] = '\0';
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
return (string);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
** print the string
|
|
||||||
*/
|
|
||||||
|
|
||||||
int ft_put_word(char *s)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
i = ft_strlen(s);
|
|
||||||
ft_putstr(s);
|
|
||||||
return (i);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
** -receive 'i' the number in which '*' will expand
|
|
||||||
** -turn it into a string
|
|
||||||
** -calculate the total lentgh of the string '%...' for nbr replacing '*'
|
|
||||||
** -allocate a new string with this length
|
|
||||||
** -copy the original str with first '*' expanded into it's corresponding nbr
|
|
||||||
*/
|
|
||||||
|
|
||||||
int ft_expand_star(int nbr, char **string)
|
|
||||||
{
|
|
||||||
char *s;
|
|
||||||
char *n;
|
|
||||||
int i;
|
|
||||||
int j;
|
|
||||||
int k;
|
|
||||||
|
|
||||||
n = ft_itoa(nbr);
|
|
||||||
if (!(s = ft_memalloc(sizeof(char) * (ft_strlen(n) + ft_strlen(*string)))))
|
|
||||||
return (0);
|
|
||||||
i = -1;
|
|
||||||
j = 0;
|
|
||||||
k = 0;
|
|
||||||
while ((*string)[++i] != '\0')
|
|
||||||
{
|
|
||||||
s[j] = (*string)[i];
|
|
||||||
if (s[j] == '*')
|
|
||||||
while (n[k] != '\0')
|
|
||||||
s[j++] = n[k++];
|
|
||||||
else
|
|
||||||
j++;
|
|
||||||
}
|
|
||||||
free(n);
|
|
||||||
free(*string);
|
|
||||||
*string = s;
|
|
||||||
return (1);
|
|
||||||
}
|
|
||||||
@@ -1,12 +1,12 @@
|
|||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
/* */
|
/* */
|
||||||
/* ::: :::::::: */
|
/* ::: :::::::: */
|
||||||
/* ft_width_n_precision.c :+: :+: :+: */
|
/* ft_flag_transform.c :+: :+: :+: */
|
||||||
/* +:+ +:+ +:+ */
|
/* +:+ +:+ +:+ */
|
||||||
/* By: hulamy <marvin@42.fr> +#+ +:+ +#+ */
|
/* By: hulamy <marvin@42.fr> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2020/02/25 14:48:55 by hulamy #+# #+# */
|
/* Created: 2020/02/27 11:55:43 by hulamy #+# #+# */
|
||||||
/* Updated: 2020/02/26 19:24:18 by hulamy ### ########.fr */
|
/* Updated: 2020/02/27 11:55:45 by hulamy ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
@@ -154,3 +154,14 @@ char *ft_width(char *s, char *print)
|
|||||||
return (print);
|
return (print);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** go through all the transformation flags needs
|
||||||
|
*/
|
||||||
|
|
||||||
|
char *ft_flag_transform(char *s, char *print, char *type)
|
||||||
|
{
|
||||||
|
print = ft_precision(s, print, type);
|
||||||
|
print = ft_width(s, print);
|
||||||
|
return (print);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user