-
Notifications
You must be signed in to change notification settings - Fork 0
/
_printf.c
executable file
·129 lines (106 loc) · 2.47 KB
/
_printf.c
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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
#include "main.h"
/**
* print_with_format - recognize format on passed buffer and
* return pointer to its function
*
* @buffer: pointer to string
* @idx: pointer to index that start from it
* Return: (NULL) if format not recognized, otherwise pointer to function
*/
int (*print_with_format(const char *buffer, int *idx))()
{
/* format dictionary maps formats with it's functions */
formater format_dic[] = {
{"c", printf_char},
{"s", printf_string},
{"d", printf_dec},
{"i", printf_int}
};
int dic_len = 4; /* lenght of format_dic */
int tmp_idx = *idx;
int j;
/* iterate over format_dic to check if any format matched */
while (dic_len--)
{
tmp_idx = *idx;
j = 0;
while (buffer[tmp_idx] && format_dic[dic_len].flag[j]
&& buffer[tmp_idx] == format_dic[dic_len].flag[j])
++tmp_idx, ++j;
/* current flag in format_dic matched */
if (!format_dic[dic_len].flag[j])
break;
}
/* no flag in format_dic matched */
if (dic_len < 0)
return (NULL);
/* move idx to point on char after format */
*idx = tmp_idx;
return (format_dic[dic_len].print_with_format);
}
/**
* do_formated_print - take buffer and iterate over it tohandle mulitple %
*
* @buffer: buffer of string
* @idx: pointer to idx
* @written: pointer to writen
*
* Return: (1) use formated printf, (0) otherwise
*/
int do_formated_print(const char *buffer, int *idx, int *written)
{
int flag = 1;
while (buffer[*idx + 1] && buffer[*idx + 1] == '%')
{
flag = !flag;
if (!flag)
{
_putchar(buffer[*idx]);
(*written)++;
}
(*idx)++;
}
(*idx)++;
return (flag);
}
/**
* _printf - print buffer stream to output stream
*
* @format: buffer of chars
* @...: formated arguments
* Return: number of chars that printf sucessfully printed them
*/
int _printf(const char *format, ...)
{
int idx = 0,
written = 0;
int (*formated_printf)();
va_list args;
if (!format) /* case of nullable buffer */
return (-1);
va_start(args, format);
while (format[idx])
{
if (format[idx] == '%') /* case with formatting */
{
/* case if i have even number of % so i still have % not printed */
if (!do_formated_print(format, &idx, &written))
continue;
formated_printf = print_with_format(format, &idx);
if (!formated_printf)
{
_putchar('%');
written++;
continue;
}
written += formated_printf(args);
}
else /* case of chars in buffer */
{
_putchar(format[idx++]);
++written;
}
}
va_end(args);
return (written);
}