How to customize printf in C

Поділитися
Вставка
  • Опубліковано 10 гру 2024

КОМЕНТАРІ • 51

  • @ciren___
    @ciren___ 2 роки тому +27

    I'm not sure this'll ever be of use to me, especially with the amount of pointer casting that I'd rather avoid, but that was nonetheless really interesting to know and see working, thanks!

  • @unperrier5998
    @unperrier5998 2 роки тому +4

    Thank you Jacob for the mention.
    For the short but explanatory video format that is yours, I had in mind a simple wrapper around printf() that would only handle the "%U" string (with only one argumentto printf), not in confunction with other formats and arguments. But your approach is better yet concise, although GNU specific.

  • @DenisovichDev
    @DenisovichDev 2 роки тому +3

    Learnt a lot from this video! Wanna see more deep dives like this one

  • @lawrencedoliveiro9104
    @lawrencedoliveiro9104 2 роки тому +5

    Interesting that your callback is always given a FILE*, while the printf family includes functions for writing to preallocated strings, dynamically-allocated strings, and even direct file descriptors.
    Presumably in all these cases, the glibc wrapper creates temporary FILE* objects as the common denominator for invoking your callback, and likely all the rest of its internal machinery as well.

  • @anon_y_mousse
    @anon_y_mousse 2 роки тому +7

    This is certainly neat, and I wish they would add such functionality to the standard, albeit in a slightly different way. This is at least part of why I've been developing my own language. Sometimes it feels a bit like an addiction. It all started with implementing the functions in string.h and by the time I got done rewriting libc, I just couldn't stop. By the time I'm done, it may actually be enticing enough for others to use it, assuming I ever release it. You've actually inspired me to add a few features into my language. This video only reinforced my belief that I was right to extend my own printf() and have a way to add format specifiers. Though, it won't be compatible with C's printf(), at least not fully, even by default.

  • @sillybuttons925
    @sillybuttons925 2 роки тому +1

    Logging in c would be a good one. Like different handlers, streams etc.

  • @rustycherkas8229
    @rustycherkas8229 2 роки тому +1

    Funny that one can do that in UNIX derivative Linux.
    The UNIX philosophy used to be "build complexity from assembling small, simple units", not "let's muddy things because we can." 'cat' used to be simply "concatenated files to the standard output"... Then some bright lad thought it should also add line numbers... and skip numbering blank lines... and squeeze out multiple blank lines... and makes tabs visible... and make EOL visible, too... In fact, make everything visible!
    Poor cat...
    Thanks for an Interesting video,.
    My preference would be to KISS...
    Push the UUID gen/parse into a function that returns a string (formatted to suit) and simply use '%s'.
    Just because one CAN do something, does that mean one SHOULD??

  • @zxuiji
    @zxuiji 2 роки тому +2

    Certainly is interesting, didn't know you could do that, I still prefer to go with my custom version of "sprintf", basically I wrote the whole thing to just deal with UTF32 characters then had my other custom string functions just use it under the hood with some temporary buffers, added all the standard specifiers then added a couple of my own like %?b for bit sequences (where ? is d, i or u like the standard integer specifiers), and %?p to take intptr_t/uintptr_t. Took me a while to get it right (mostly because I made some errors in my string growth handlers which I didn't notice until way after I started).
    Seeing this I realise I should refactor that function and do something similar to the above, saving to watch later for now as it's not a priority, however instead of declaring the format specifier I think I'll instead go with a list of function pointers to call every time the % character is encountered, I'll also declare the built in specifiers via public functions and a macro for the lot to be put in the expected array so that the order of which specifiers to check for plus what to actually look for can be specified manually, something like:
    int xprintf( char *args, ... )
    {
    int ret;
    va_list list;
    va_start( list, args );
    ret = xprintv( args, list );
    va_end( list );
    return ret;
    }
    int stdout_foo(uuid_t id)
    {
    xprint_wr_func funcs[] = { XPRINT_WR_WITH, wr_uuid };
    xprint_wr_with with = { stdout, (vprintx_wr_cb)fwrite, funcs, sizeof(funcs) / sizeof(funcs[0]) };
    return xprintf( "%WITH%UUID", &with, &uuid );
    }

  • @azmah1999
    @azmah1999 2 роки тому +2

    In C++20 a new format function has finally been added to the standard library that allows Python style formatting of strings. It's pretty cool because you can add format specifier and it's supported by the standard! However i think only MSVC has a working implementation at the moment

    • @tk36_real
      @tk36_real 2 роки тому

      But also it's C++ 20 only (I mean technically 23 too, but you know what I mean). Also it's worse performance wise, that printing directly

    • @unperrier5998
      @unperrier5998 2 роки тому +1

      in C++ 30 we'll get python 3.6+ f-strings :)

    • @rastaarmando7058
      @rastaarmando7058 2 роки тому +1

      @@tk36_real It's WAY faster than printf.

  • @shivaramkrishnaaj9496
    @shivaramkrishnaaj9496 2 роки тому +1

    Thanks for the video... And a Request, Please make a video on explaining the In and out of Stdio.h header files, to explain how printf functions works behind the functions, how printf function uses system calls to print the data on screen.. if possible how system calls implement printing of data to console or screen, please...

  • @KangJangkrik
    @KangJangkrik 2 роки тому +1

    This might be useful when we're trying to print a struct for some reason

  • @benjaminshinar9509
    @benjaminshinar9509 2 роки тому

    amazing to see this!

  • @georgecop9538
    @georgecop9538 2 роки тому

    Just wanted to say you can use the old approach with dlsym and looping through string (and checking for %u)

  • @MohamedMohsen0
    @MohamedMohsen0 2 роки тому +1

    interesting !
    another option would be function hooking

  • @Mixmetal29
    @Mixmetal29 2 роки тому

    Your content is amazing

  • @rustycherkas8229
    @rustycherkas8229 2 роки тому

    Alternatively, one could look to the example of "strftime()" and write a more intuitive, flexible and portable function that is compiler and library independent.

  • @aashakil4596
    @aashakil4596 2 роки тому

    Hi, will you make a video on how to organize and manage between header files and source files. I actually get stuck in these organizing problem when I try to expand my project.

  • @oscareriksson9414
    @oscareriksson9414 2 роки тому

    Cool! I really want to have a use case for it! 😀

  • @casperes0912
    @casperes0912 2 роки тому +17

    This feels a bit dodgy. The fact it'll spam errors at you unless you disable the format specifier warnings would certainly keep me away from it and I'd rather find alternatives. That and dodgy documentation doesn't help either.

    • @JacobSorber
      @JacobSorber  2 роки тому +2

      Yep, it was definitely one of those, let's-see-if-we-can moments. I don't think I'll be seeing much use for this in my day-to-day programming.

    • @lawrencedoliveiro9104
      @lawrencedoliveiro9104 2 роки тому

      printf is inherently typesafe. Compiler warnings on the format string are essentially a kludge on top of a kludge; they help with the simpler cases, but just get in the way of the more advanced cases (like this one).

  • @kawcco
    @kawcco 2 роки тому +3

    Let's make printf even more non-standard!

    • @SimGunther
      @SimGunther 2 роки тому +1

      printf has a cringe implementation, but if you really wanted to, you could make your own faster print function that wasn't explicitly named printf.

  • @doowi1182
    @doowi1182 2 роки тому +2

    An alternative would be to create a custom printf wrapper using va_list that has additional logic to take care of the new format characters.

    • @unperrier5998
      @unperrier5998 2 роки тому +2

      va_list is nice but it's the tip of the iceberg as it only deals with arguments. You need to find out the size of each argument and to be compatible with printf() you'd need to implement all the cases and modifiers that printf() supports, including references to write values back into memory. The switch-case that results is big and would take a 2h video.

    • @doowi1182
      @doowi1182 2 роки тому

      @@unperrier5998 that's a good point I hadn't considered!

  • @saturdaysequalsyouth
    @saturdaysequalsyouth 2 роки тому +1

    It's probably easier to modify musl libc than glibc.

  • @bhekumuzimacdonald5967
    @bhekumuzimacdonald5967 2 роки тому

    how do l create a code that carry's out the some function as printf but without using printf and co. (fprintf, sprintf, snprintf, asprintf, dprintf, vprintf, vfprintf, vsprintf, vsnprintf, vasprintf, vdprintf)

  • @liamagordon
    @liamagordon 2 роки тому

    Hey Jacob. Could we see any videos on the Windows Kernel sometime and how we can interact with it using C?

    • @JacobSorber
      @JacobSorber  2 роки тому

      I mean, there's always a chance. That would probably require me to actually use Windows, right?
      Do you know where I can find the Windows kernel source code?

  • @mrtnsnp
    @mrtnsnp 2 роки тому

    From the header on Macos:
    /*
    * We don't support the GLIBC register_printf_function() or FreeBSD
    * register_printf_render_std(), because they affect printf globally
    * and are unsafe.
    */
    So, indeed: not very portable.

  • @yanhuang4911
    @yanhuang4911 10 місяців тому

    How to do finer control like %*.s

  • @jonweinraub
    @jonweinraub 2 роки тому

    Such a fascinating idea. Definitely learnt something new and I feel like I’m going to abuse the heck out of this idea mwuahahaha!

  • @lawrencedoliveiro9104
    @lawrencedoliveiro9104 2 роки тому

    12:47 Extra parentheses are unnecessary.

  • @michalski9141
    @michalski9141 2 роки тому +4

    still waiting for you to show up on odysee...

    • @jorionedwards
      @jorionedwards 2 роки тому

      Anyone with youtube-dl can just reupload to odysee.

  • @sc5shout
    @sc5shout 2 роки тому

    How the ":" in this "uint x:1;" is called?

    • @hedgechasing
      @hedgechasing 2 роки тому

      That is a bit field. It specifies that that member of the struct only needs on bit of storage.

  • @gabrieldelosrios811
    @gabrieldelosrios811 2 роки тому

    Why would someone chose to use C if it's not for a college assignment, it's insane

  • @chopper3lw
    @chopper3lw 2 роки тому +6

    Oh EM G! You used FILE *s and printf_info *i ... So culturally inappropriate. Longstanding unwritten norms hold that "s" will probably be a string, and "i" will probably be an integer iterator or index (or, rarely, a complex number). Additionally, in instruction material FILE *fh; is generally used. Please excuse my flame, it stems from using C since its predecessor BCPL.

    • @lawrencedoliveiro9104
      @lawrencedoliveiro9104 2 роки тому

      Fortran programmer?

    • @chopper3lw
      @chopper3lw 2 роки тому

      @@lawrencedoliveiro9104 40+ year C/Unix programmer. Although my Dad did teach me Fortran as a kid.

  • @lean.drocalil
    @lean.drocalil 2 роки тому

    I don't think I'd ever even consider using that 🎃

    • @JacobSorber
      @JacobSorber  2 роки тому +1

      I'm not sure I will either, but it was a fun adventure.

  • @SF-eg3fq
    @SF-eg3fq 2 роки тому

    bro, why do people still use this old language, don't you think it is time to switch to a more modern solutions (i.e rust)?. if you think about it. using c will always lead to memory corruption issues no matter how good you are

  • @SIGMA_BLYAT
    @SIGMA_BLYAT 2 роки тому

    this video about nothing