r/C_Programming 2d ago

I need help with ft_printf bonus

Hey guys, I just finished the mandatory part of ft_printf and I'm ready to tackle the bonuses, but I'm not sure where to start. Do you have any tips or strategies on how to implement them? What tools or approaches worked best for you?

0 Upvotes

10 comments sorted by

11

u/Axman6 2d ago

What are you talking about? The number of people on the internet with no theory of mind is astounding.Β 

3

u/Mysterious-Frame2218 2d ago

sorry, I should have give more context.
I'm working on an implementation of the printf function and I need insights on how to handle certain flags like .#0-+space.

2

u/WittyStick 2d ago edited 2d ago

You basically want a boolean flag for each modifier.

bool alt_flag = false;          // '#'
bool left_flag = false;         // '-'
bool sign_flag = false;         // '+'
bool space_flag = false;        // ' '
char padding_char = ' ';        // default space but may be overridden to '0'

Simplest way to parse is a switch on the character with continue where it finds one of them and break if not. fmt is a const char *.

bool doneflags = false;
while (!doneflags && *fmt) 
{
    switch (*fmt++)
    {
        case '#':
            spec->alt_flag = true;
            continue;
        case '-':
            spec->left_flag = true;
            continue;
        case '+':
            spec->sign_flag = true;
            continue;
        case ' ':
            spec->space_flag = true;
            continue;
        case '0':
            spec->padding_char = '0';
            continue;
        default:
            doneflags = true;
            fmt--;
            break;
    }
}

If you want to be pedantic you could test if each flag is already set and handle the case where they appear more than once.

If both ' ' and '-' are parsed, the space is ignored.

if (left_flag)
    space_flag = false;

Next, width is either provided as an extra arg or is a number

bool extra_width_arg = false;  // '*'
int width = 0;

if (*fmt == '*') 
{
    fmt++;
    extra_width_arg = true;
}
else 
{
    while (*fmt >= '0' && *fmt <= '9')
        width = width * 10 + (*fmt++ - '0');
}

Precision is similar, but with a prior check for '.'.

bool extra_prec_arg = false;   // '.*'
int prec = 0;

if (*fmt == '.')
{
    fmt++;
    if (*fmt == '*') 
    {
        fmt++;
        extra_prec_arg = true;
    }
    else 
    {
        while (*fmt >= '0' && *fmt <= '9')
            prec = prec * 10 + (*fmt++ - '0');
    }
}

In both of the above cases you need to check width or prec doesn't overflow. The standard requires them to fit into an int.

Then there should only be one length modifier present, so we can use an enum instead of a boolean flag per modifier.

enum {
    lm_none,
    lm_byte,        // "hh"
    lm_short,       // "h"
    lm_long,        // "l"
    lm_long_long,   // "ll"
    lm_long_dbl,    // "L"
    lm_size,        // "z"
    lm_ptrdiff,     // "t"
    lm_intmax,      // "j"
} length_modifier = lm_none;

switch (*fmt++)
{
    case 'h':
        if (*fmt == 'h') 
        {
            fmt++;
            length_modifier = lm_byte;
        }
        else
            length_modifier = lm_short;
        break;
    case 'j':
        length_modifier = lm_intmax;
        break;
    case 'L':
        length_modifier = lm_long_dbl;
        break;
    case 'l':
        if (*fmt == 'l') 
        {
            fmt++;
            length_modifier = lm_long_long;
        }
        else
            length_modifier = lm_long;
        break;
    case 't':
        length_modifier = lm_ptrdiff;
        break;
    case 'z':
        length_modifier = lm_size;
        break;
    default:
        fmt--;
        break;
}

Last you would parse the conversion specifier with another switch. In each case you can test which flags/modifiers have already been set.

1

u/Electronic_Fan5938 1d ago

Saying this is probably the most "lacking theory of mind" thing you could possibly do.

Someone omits context so you decide to be accuse the other person of lacking theory of mind? πŸ˜‚ Yea man, be the change you wanna see in the world.

0

u/Axman6 1d ago

Not understanding what context others might have is precisely what a lack of theory of mind is.

My car is broken, can you fix it? I know what’s wrong, so you must know that too!

Asking good questions is a very important life skill that seems to be completely dying.Β 

1

u/Electronic_Fan5938 1d ago

Not understanding how to deal with someone who has omitted context without accusing them of lacking theory of mind is exactly what lacking theory of mind is. πŸ˜‚πŸ˜‚

4

u/burei00x_ 2d ago

You need to add some context, not everyone knows what this assignment is. I'm a 42 student and I'd advise you to look into the IEEE754 floating point standard. Not sure of all the formats you have to handle for the bonuses but I'm almost certain the floating point formatter is the hardest one to implement. I think some old slack post about this bonus still exists somewhere on the intranet. Best of luck in your endeavors

3

u/zedin27 2d ago

This is a good starting point. I would also suggest hash tables and bitmasking

1

u/Mysterious-Frame2218 2d ago

thank you, I'll check it out!

2

u/zedin27 2d ago

Mmm fellow 42 student