Portable printf extension ?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • lithiumcat@gmail.com

    Portable printf extension ?

    Hi,

    I was wondering whether there is a standard-compliant way to extend
    printf with a new %code that is not yet reserved (e.g. %r) with a
    given argument type.

    My guess would be to write a function that looks like « int
    my_printf(const char *fmt, ...); », with a special processing of fmt
    to replace the new %code with the correct data, and then hand over the
    processed fmt and the remaining arguments to vprintf.

    However I don't know much about variable arguments, but the standards
    seems pretty light about what can be done with them. So I have no idea
    of how to write such a my_printf function.

    Is there a protable way to do this within the C? If anybody knows,
    although it's a bit off-topic, would POSIX allow it if standard C
    doesn't? (btw, what is the topical newsgroup for such POSIX-related
    questions?)

    On a side note, although I'm interested in the answers to the
    questions above for my general knowledge of C, the problem I'm trying
    to solve is fprintf-ing and snprintf-ing a non-C string, represented
    by a struct containing a char* (that is not zero-terminated) and a
    size_t length. So I'm also interested in a solution for that
    particular problem. For now I'm using a sequence of fprintf/fwrite/
    fprintf/... or snprintf/memcpy/snprintf/... but that looks ugly
    (especially with the size checks in the second case).
  • rahul

    #2
    Re: Portable printf extension ?

    If your char array is not null terminated, you will have to use
    various formatted input/output function that you are already using.
    There isn't a way to extend printf and the thing you are suggesting is
    to wrap the call in your own user-defined function. Here is one
    introductory tutorial about variable number of arguments:


    Comment

    • Richard Bos

      #3
      Re: Portable printf extension ?

      rahul <rahulsinner@gm ail.comwrote:

      [ Do _not_ snip all context from posts - quote enough material to make
      it clear what you are talking about.
      No, using Google Broken Groups Beta is _not_ an excuse. ]
      If your char array is not null terminated, you will have to use
      various formatted input/output function that you are already using.
      There isn't a way to extend printf and the thing you are suggesting is
      to wrap the call in your own user-defined function.
      It is quite possible to output non-null-terminated char arrays using the
      Standard printf() only, _if_ you know how many characters you want to
      print, _and_ there are enough characters in the array.

      Hint: precision specifier.

      Richard

      Comment

      • lithiumcat@gmail.com

        #4
        Re: Portable printf extension ?

        On Jun 4, 12:54 pm, r...@hoekstra-uitgeverij.nl (Richard Bos) wrote:
        rahul <rahulsin...@gm ail.comwrote:
        It is quite possible to output non-null-terminated char arrays using the
        Standard printf() only, _if_ you know how many characters you want to
        print, _and_ there are enough characters in the array.
        >
        Hint: precision specifier.
        Thanks a lot for that hint, I had completely forgotten about that
        specifier. I did thought about the field width specifier (using a star
        to get the width from the argument), but that doesn't do what I need.
        I guess I forgot the precision because I have never used it.

        So the call would look like that:

        char *char_array_wit hout_nul;
        size_t char_array_size ;
        [proper initialization]
        printf("Here is the string: \"%.*s\"\n", (int)char_array _size,
        char_array_with out_nul);

        If I understand correctly, the cast is needed because int and size_t
        might not have the same size (signedness shouldn't an issue as long as
        char_array_size is not too large to fit in an int). Right?

        Comment

        • Richard Bos

          #5
          Re: Portable printf extension ?

          lithiumcat@gmai l.com wrote:
          So the call would look like that:
          >
          char *char_array_wit hout_nul;
          size_t char_array_size ;
          [proper initialization]
          printf("Here is the string: \"%.*s\"\n", (int)char_array _size,
          char_array_with out_nul);
          >
          If I understand correctly, the cast is needed because int and size_t
          might not have the same size (signedness shouldn't an issue as long as
          char_array_size is not too large to fit in an int). Right?
          Right.

          With the proviso that if char_array_size is not correct, but is in fact
          larger than the real size of your array, you invoke undefined behaviour;
          so just don't do that. But in that, it is no different from, say,
          memcpy(). Also, if there _is_ by chance a nul character in your array,
          nothing beyond it gets printed.

          Richard

          Comment

          • Keith Thompson

            #6
            Re: Portable printf extension ?

            rlb@hoekstra-uitgeverij.nl (Richard Bos) writes:
            lithiumcat@gmai l.com wrote:
            >
            >So the call would look like that:
            >>
            >char *char_array_wit hout_nul;
            >size_t char_array_size ;
            >[proper initialization]
            >printf("Here is the string: \"%.*s\"\n", (int)char_array _size,
            >char_array_wit hout_nul);
            >>
            >If I understand correctly, the cast is needed because int and size_t
            >might not have the same size (signedness shouldn't an issue as long as
            >char_array_siz e is not too large to fit in an int). Right?
            >
            Right.
            >
            With the proviso that if char_array_size is not correct, but is in fact
            larger than the real size of your array, you invoke undefined behaviour;
            so just don't do that. But in that, it is no different from, say,
            memcpy(). Also, if there _is_ by chance a nul character in your array,
            nothing beyond it gets printed.
            To be precise, neither the nul character nor anything beyond it gets
            printed.

            --
            Keith Thompson (The_Other_Keit h) kst-u@mib.org <http://www.ghoti.net/~kst>
            Nokia
            "We must do something. This is something. Therefore, we must do this."
            -- Antony Jay and Jonathan Lynn, "Yes Minister"

            Comment

            Working...