ft_printf 42

Geral

 NÃO COPIE, ENTENDA!!

Protótipo da função:

1
int ft_prinf(const char *, ...)

A ideia é reescrever a função printf()

repo no github

Descrição

Uma pequena descrição das conversões requeridas:

• %c imprime um único caractere.

• %s imprime uma string.

• %p O argumento void * ponteiro é impresso em hexadecimal.

• %d imprime um número decimal (base 10).

• %i imprime um inteiro na base 10.

• %u imprime um número decimal sem sinal (base 10).

• %x imprime um número em hexadecimal (base 16).

• %% imprimir um sinal de porcentagem.


pdf


A primeira coisa a se fazer é criar uma variável do tipo va_list, sendo assim:

1
va_list ap

e daí chamamos a macro va_start(va_list ap, last_arg) onde o last_arg é o ultimo argumento conhecido da função, antes das “…”:

1
2
3
4
5
6
7
//Se a func for a ft_printf 
int ft_prinf(const char *format, ...)


va_list ap; //criando a variavel ap do tipo va_list
//a macro seria declarada dessa forma:
va_start(ap, format);

💻 Então, a base da ft_printf é basicamente assim:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
int	ft_printf(const char *format, ...)
{
va_list ap;
int i;
int ret;

i = 0;
ret = 0;
va_start(ap, format);

/*
* Nesse laço a ideia é ele percorrer toda a string contida em format até o final,
* que no caso é um '\0'
*/
while (format[i])
{
/*
* Aqui verifico se o caracter '%' existe, se ele existe faço uma verificação
* se algum dos caracteres passados em seguida são flags da printf com a função
* ➡️ ft_strchr()⬅️ que se você chegou até aqui sabe como ela funciona
*/
if (format[i] == '%' && ft_strchr("cspdiuxX%", format[i + 1]))
{
ret += ft_printf_arg(format, i, ap);
i++;
}
/*
* Caso não encontre, o caracter sera impresso e somado a "ret" que é o controle
* de quantos caracteres foram impressos.
*/
else
ret += ft_putchar(format[i]);
i++;
}
va_end(ap);
return (ret);
}

caso não tenha visto a strchr acesse aqui e aqui.

a função ft_printf_arg(const char *fmt, int i, va_list ap) serve como um switch case, pra cada flag que recebe:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
/*
* Aqui é feito a verificação de qual flag foi passada, e em cada caso há uma função
* específica de impressão e retorna a quantidade de caracter impresso
*/

int ft_printf_arg(const char *fmt, int i, va_list ap)
{
if (fmt[i + 1] == '%')
return (ft_putchar(fmt[i + 1]));
else if (fmt[i + 1] == 'c')
return (ft_putchar(va_arg(ap, int)));
else if (fmt[i + 1] == 's')
return (ft_putstr(va_arg(ap, char *)));
else if (fmt[i + 1] == 'd' || fmt[i + 1] == 'i')
return (ft_putnbr(va_arg(ap, int)));
else if (fmt[i + 1] == 'u')
return (putnbr_u(va_arg(ap, unsigned int)));
else if (fmt[i + 1] == 'x' || fmt[i + 1] == 'X')
{
if (fmt[i + 1] == 'X')
return (put_hex(va_arg(ap, unsigned int), "0123456789ABCDEF"));
else
return (put_hex(va_arg(ap, unsigned int), "0123456789abcdef"));
}
else if (fmt[i + 1] == 'p')
return (ft_putstr("0x") + put_pointer(va_arg(ap, void *), \
"0123456789abcdef"));
else
return (0);
}
Função ft_putchar()

A função putchar() foi desenvolvida no projeto libft, e ela imprime um caracter com a função write(). Usei uma personalizada, já que a saída seria a padrão.

1
2
3
4
5
int	ft_putchar(char c)
{
write (1, &c, 1);
return (1);
}
Função ft_putstr()

A putstr() imprime uma cadeia de caracteres. Ela precisou também ser personalizada, pois quando recebido uma string vazia, deve ser impresso na saida padrão a string (null) .

1
2
3
4
5
6
7
8
9
10
11
12
13
int	ft_putstr(char *str)
{
int len;

if (!str)
{
write (1, "(null)", 6);
return (6);
}
len = ft_strlen(str);
write (1, str, len);
return (len);
}
ft_putnbr()

Imprime os caracteres que representam os numeros. Como a write() só imprime caracteres, é preciso transformar os numeros em string, e pra isso a função itoa é usada.

1
2
3
4
5
6
7
8
9
10
int	ft_putnbr(int nbr)
{
char *str;
int len;

str = ft_itoa(nbr);
len = ft_putstr(str);
free(str);
return (len);
}
putnbr_u

Uma variação da putnbr() e da itoa , a diferença é que recebem como parâmentro um unsigned int.

1
2
3
4
5
6
7
8
9
10
int	putnbr_u(unsigned int nbr)
{
char *str;
int len;

str = ft_utoa(nbr);
len = ft_putstr(str);
free(str);
return (len);
}

Inicio