Search code examples
cstdiounistd.h

My prints in the standard output aren't in good order


i want to do a function that deletes printed characters in the standard output. However it turns out that it prints the '\b' before my actual printf I tried to print a t it prints it before as well. I print the '\b' with my own function however it does work with putchar. I dont understand why.

Here's my code:

void    ft_putchar_a(char c)
{
    write(1, &c, 1);
}

void    delete_std(int n)
{
    int i;

    i = 0;
    while (i < n)
    {
        ft_putchar_a('\b');
        i++;
    }
}

int main()
{
    printf("Hello");
    delete_std(5);
    return (0);
}

Solution

  • The problem you have is pretty simple. The standard library maintains a buffer of data it's writing to each file (including standard output). printf writes data to that buffer.

    write normally does not use that buffer. So, you're writing data into the buffer, then calling write to write "past" the buffer, then as your program exits, the data gets flushed from the buffer to the stream--but the backspace has already been written.

    There are a couple ways you could deal with this. The simplest would be to use standard C output routines for all the data. For example:

    void    ft_putchar_a(char c)
    {
    //    write(1, &c, 1);
          fputc(c, stdout); 
    }
    

    This way, all the output will be written to the buffer, and remain in order. You could (theoretically) do all the output via write instead, but unless you add some buffering of your own, that's going to be pretty inefficient (which is why the standard library does buffering in the first place).

    Another possibility (but kind of an ugly one, IMO) would be to flush the buffer after you write via printf:

    printf("Hello");
    fflush(stdout);
    delete_std(5);
    

    This will make this specific code work, but leaves the fundamental problem, so anytime you use your ft_putchar_a, you'll run into the same thing. I suppose you could incorporate the patch into ft_putchar_a itself to at least ensure it happens consistently:

    void f_putchar_a(char c) {
         fflush(stdout);
         write(1, &c, 1);
    }
    

    ...but using C output throughout is much cleaner and more straighforward.