I have a project of recreating printf in my school.
I don't want to check the format specifiers for characters all the time in my code, as I find it messy, and ugly.
As for now, I have found a way by creating some global constant array, and checking using those. But I don't like the idea of having so many global variables in my code as well.
Is it one of those cases were global variables are ok? Or should I use another method to get what I want?
Here is how I'm starting:
Global const array
const char g_sp_integer[] = {
'd', //signed decimal int
'i', //signed decimal int
'o', //unsigned octal
'u', //unsigned decimal int
'x', //unsigned hex int
'X', //unsigned hex int (uppercase)
'\0'
};
My header
#ifndef FT_PRINTF_H
# define FT_PRINTF_H
# include <stdarg.h>
# include <stdint.h>
# include <stdlib.h>
# include "libft.h"
# define SUCCESS (int32_t)0
# define FAILURE (int32_t)-1
/*
** Those extern definitions are used to check the specifier flags
*/
extern const char *g_sp_integer;
int ft_printf(const char *format, ...);
#endif
And my printf function
#include "ft_printf.h"
static int32_t is_sp_integer(char c)
{
uint32_t i;
while (g_sp_integer[i] != '\0')
{
if (g_sp_integer[i] == c)
return (i);
++i;
}
return (FAILURE);
}
int ft_printf(const char *format, ...)
{
va_list ap;
char *tmp;
int32_t sp_type;
tmp = format;
va_start(ap, format);
while (tmp != '\0')
{
if (tmp != '%')
{
ft_putchar(tmp);
continue;
}
if ((sp_type = is_sp_integer(++tmp)) != FAILURE)
; //parse_flag(sp_type);
//continue checking the type of the specifier
}
va_end(ap);
return (SUCCESS);
}
What I want to avoid:
Those are just bare-bones prototype, but I would like to know if there is a proper way to make my function as clean as that. Which means, in my opinion, that I'd like to avoid doing the check like this, if possible:
if (c == 'd' || c == 'i')
//manage the integer flag
else if (c == 'o')
//manage the octal flag, etc.
If it not possible and the best way is the one I'd like to avoid, please, let me know!
Thank you all for your patience, as finding good practices can sometimes be hard!
EDIT:
Solution I used:
While the first solution has the global answer to what I should have done in this case (which is using a static variable in that file), I have ended doing what was suggested in the second answer, as it fits my needs, and avoid using static or global variables.
Here is my function's code:
static int32_t is_sp_integer(char c) {
const char *sp_integer;
const char *sp_ptr;
sp_integer = "dDioOuUxX";
sp_ptr = sp_integer;
while (*sp_ptr != '\0')
{
if (*sp_ptr == c)
return (sp_ptr - sp_integer);
++sp_ptr;
}
return (FAILURE);
}
Thanks to all of you!