skipping parameters with printf

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • John Devereux

    skipping parameters with printf

    Hi,

    I would like to know if their is a conversion specifier, or other
    method, that will allow me to not use particular arguments to printf.

    Failing that, is it permissable to simply "not use" the parameter if
    it is at the end of the parameter list?


    For example,

    printf("%02d:%0 2d:%02d", hours, minutes, seconds); /* 11:59:00 */
    printf("%02d:%0 2d", hours, minutes, seconds); /* 11:59 */


    Thanks,


    --

    John Devereux
  • Walter Roberson

    #2
    Re: skipping parameters with printf

    In article <87psrjsdsu.fsf @cordelia.dever eux.me.uk>,
    John Devereux <jdREMOVE@THISd evereux.me.uk> wrote:[color=blue]
    >I would like to know if their is a conversion specifier, or other
    >method, that will allow me to not use particular arguments to printf.[/color]
    [color=blue]
    >Failing that, is it permissable to simply "not use" the parameter if
    >it is at the end of the parameter list?[/color]
    [color=blue]
    >For example,[/color]
    [color=blue]
    > printf("%02d:%0 2d:%02d", hours, minutes, seconds); /* 11:59:00 */
    > printf("%02d:%0 2d", hours, minutes, seconds); /* 11:59 */[/color]

    Answering your second question: when printf() and kin reach the
    end of the conversion specification, they stop attempting to convert
    values, so your second example will be fine.

    Answering your first question: The C89 standard does not offer any
    mechanism to "skip" values or convert them out of order.

    There is a common extension to the printf family which offers a
    prefix immediately after the %, consisting of an argument number
    followed by a $ and when this appears, the specified value is the
    next one converted. Note that $ is not a part of the standard C
    character set, so this extension is doubly non-portable.
    --
    Any sufficiently old bug becomes a feature.

    Comment

    • Irrwahn Grausewitz

      #3
      Re: skipping parameters with printf

      John Devereux <jdREMOVE@THISd evereux.me.uk> wrote:[color=blue]
      >I would like to know if their is a conversion specifier, or other
      >method, that will allow me to not use particular arguments to printf.
      >
      >Failing that, is it permissable to simply "not use" the parameter if
      >it is at the end of the parameter list?
      >
      >For example,
      >
      > printf("%02d:%0 2d:%02d", hours, minutes, seconds); /* 11:59:00 */
      > printf("%02d:%0 2d", hours, minutes, seconds); /* 11:59 */[/color]

      It's ok to pass more arguments to printf than are to be consumed by
      the format specifiers (but, of course, not the other way round).

      From ISO/IEC 9899:1999 (E) 7.19.6.1p2:
      [...] If there are insufficient arguments for the format, the
      behavior is undefined. If the format is exhausted while arguments
      remain, the excess arguments are evaluated (as always) but are
      otherwise ignored. [...]

      Best regards
      --
      Irrwahn Grausewitz (irrwahn35@free net.de)
      welcome to clc : http://www.ungerhu.com/jxh/clc.welcome.txt
      clc faq-list : http://www.faqs.org/faqs/C-faq/faq/
      clc frequent answers: http://benpfaff.org/writings/clc.

      Comment

      • Robert Gamble

        #4
        Re: skipping parameters with printf

        On Thu, 08 Sep 2005 17:13:26 +0000, Walter Roberson wrote:
        [color=blue]
        > In article <87psrjsdsu.fsf @cordelia.dever eux.me.uk>,
        > John Devereux <jdREMOVE@THISd evereux.me.uk> wrote:[color=green]
        >>I would like to know if their is a conversion specifier, or other
        >>method, that will allow me to not use particular arguments to printf.[/color]
        >[color=green]
        >>Failing that, is it permissable to simply "not use" the parameter if
        >>it is at the end of the parameter list?[/color]
        >[color=green]
        >>For example,[/color]
        >[color=green]
        >> printf("%02d:%0 2d:%02d", hours, minutes, seconds); /* 11:59:00 */
        >> printf("%02d:%0 2d", hours, minutes, seconds); /* 11:59 */[/color]
        >
        > Answering your second question: when printf() and kin reach the
        > end of the conversion specification, they stop attempting to convert
        > values, so your second example will be fine.
        >
        > Answering your first question: The C89 standard does not offer any
        > mechanism to "skip" values or convert them out of order.[/color]

        There is no way to do this in C99 either. In fact, I don't even think
        it would be possible to design a version that did do this with the current
        stdarg facility since it would need to know the type of the value being
        skipped to access arguments after it.
        [color=blue]
        > There is a common extension to the printf family which offers a
        > prefix immediately after the %, consisting of an argument number
        > followed by a $ and when this appears, the specified value is the
        > next one converted. Note that $ is not a part of the standard C
        > character set, so this extension is doubly non-portable.[/color]

        I am pretty sure the $n feature is part of the Posix standard so it is
        portable systems implementing Posix. When using this notation you have
        to use it exclusively when accessing parameters used in the format
        string. You can't use this feature to "skip" arguments either since there
        can't be gaps in the indexes for the reason mentioned above.

        Robert Gamble

        Comment

        • Anonymous 7843

          #5
          Re: skipping parameters with printf

          In article <87psrjsdsu.fsf @cordelia.dever eux.me.uk>,
          John Devereux <jdREMOVE@THISd evereux.me.uk> wrote:[color=blue]
          >
          >
          > printf("%02d:%0 2d:%02d", hours, minutes, seconds); /* 11:59:00 */
          > printf("%02d:%0 2d", hours, minutes, seconds); /* 11:59 */[/color]

          Have you considered strftime()?

          Comment

          • Walter Roberson

            #6
            Re: skipping parameters with printf

            In article <pan.2005.09.08 .21.47.56.78105 6@gmail.com>,
            Robert Gamble <rgamble99@gmai l.com> wrote:[color=blue]
            >On Thu, 08 Sep 2005 17:13:26 +0000, Walter Roberson wrote:[/color]
            [color=blue][color=green]
            >> There is a common extension to the printf family which offers a
            >> prefix immediately after the %, consisting of an argument number
            >> followed by a $ and when this appears, the specified value is the
            >> next one converted. Note that $ is not a part of the standard C
            >> character set, so this extension is doubly non-portable.[/color][/color]
            [color=blue]
            >I am pretty sure the $n feature is part of the Posix standard so it is
            >portable systems implementing Posix.[/color]


            It is not part of POSIX.1-1990; possibly a different POSIX binding.

            [color=blue]
            >When using this notation you have
            >to use it exclusively when accessing parameters used in the format
            >string. You can't use this feature to "skip" arguments either since there
            >can't be gaps in the indexes for the reason mentioned above.[/color]

            That sounds reasonable; I'd have to find the appropriate standard to
            see. The man page I happen to be looking at (SGI IRIX) phrases it this way:

            When numbered argument specifications are used, specifying the Nth
            argument requires that all the leading arguments, from the first to the
            (N-1)th, be specified at least once, in a consistent manner, in the
            format string.

            and there is no format specifier or modifier present on this system that
            allows for the possibility of supressing output.
            --
            Entropy is the logarithm of probability -- Boltzmann

            Comment

            • Robert Gamble

              #7
              Re: skipping parameters with printf

              On Thu, 08 Sep 2005 22:10:04 +0000, Walter Roberson wrote:
              [color=blue]
              > In article <pan.2005.09.08 .21.47.56.78105 6@gmail.com>, Robert Gamble
              > <rgamble99@gmai l.com> wrote:[color=green]
              >>On Thu, 08 Sep 2005 17:13:26 +0000, Walter Roberson wrote:[/color]
              >[color=green][color=darkred]
              >>> There is a common extension to the printf family which offers a prefix
              >>> immediately after the %, consisting of an argument number followed by
              >>> a $ and when this appears, the specified value is the next one
              >>> converted. Note that $ is not a part of the standard C character set,
              >>> so this extension is doubly non-portable.[/color][/color]
              >[color=green]
              >>I am pretty sure the $n feature is part of the Posix standard so it is
              >>portable systems implementing Posix.[/color]
              >
              >
              > It is not part of POSIX.1-1990; possibly a different POSIX binding.[/color]

              It's in the 2003 Edition but it is marked as an XSI entension, which I
              didn't realize in my initial post as I hadn't checked, so it is possible
              that some Posix conforming platforms won't support it.
              [color=blue][color=green]
              >>When using this notation you have
              >>to use it exclusively when accessing parameters used in the format
              >>string. You can't use this feature to "skip" arguments either since
              >>there can't be gaps in the indexes for the reason mentioned above.[/color]
              >
              > That sounds reasonable; I'd have to find the appropriate standard to
              > see. The man page I happen to be looking at (SGI IRIX) phrases it this
              > way:
              >
              > When numbered argument specifications are used, specifying the Nth
              > argument requires that all the leading arguments, from the first to
              > the (N-1)th, be specified at least once, in a consistent manner, in
              > the format string.[/color]

              Here is how my man page puts it (glibc 2.3.4):

              The C99 standard does not include the style using `$', which comes from
              the Single Unix Specification. If the style using `$' is used, it must
              be used throughout for all conversions taking an argument and all width
              and precision arguments, but it may be mixed with `%%' formats which do
              not consume an argument. There may be no gaps in the numbers of arguments
              specified using `$'; for example, if arguments 1 and 3 are specified,
              argument 2 must also be specified somewhere in the format string.

              If you want to look it up in the standard its in the "System Interfaces"
              volume of the IEEE Std 1003.1 specification (I was looking at the 2003
              Edition).

              Robert Gamble

              Comment

              • John Devereux

                #8
                Re: skipping parameters with printf

                anon7843@exampl e.com (Anonymous 7843) writes:
                [color=blue]
                > In article <87psrjsdsu.fsf @cordelia.dever eux.me.uk>,
                > John Devereux <jdREMOVE@THISd evereux.me.uk> wrote:[color=green]
                > >
                > >
                > > printf("%02d:%0 2d:%02d", hours, minutes, seconds); /* 11:59:00 */
                > > printf("%02d:%0 2d", hours, minutes, seconds); /* 11:59 */[/color]
                >
                > Have you considered strftime()?[/color]

                I probably should have...

                Thanks all for the help.

                --

                John Devereux

                Comment

                • Lawrence Kirby

                  #9
                  Re: skipping parameters with printf

                  On Thu, 08 Sep 2005 17:47:57 -0400, Robert Gamble wrote:
                  [color=blue]
                  > On Thu, 08 Sep 2005 17:13:26 +0000, Walter Roberson wrote:[/color]

                  ....
                  [color=blue][color=green]
                  >> Answering your first question: The C89 standard does not offer any
                  >> mechanism to "skip" values or convert them out of order.[/color]
                  >
                  > There is no way to do this in C99 either. In fact, I don't even think
                  > it would be possible to design a version that did do this with the current
                  > stdarg facility since it would need to know the type of the value being
                  > skipped to access arguments after it.[/color]

                  It would be easy enough to skip values using a mechanism similar to
                  scanf()'s * assignment suppression flag. The conversion specifier would
                  still determine the type of the corresponding argument.

                  Lawrence

                  Comment

                  • Robert Gamble

                    #10
                    Re: skipping parameters with printf

                    Lawrence Kirby wrote:[color=blue]
                    > On Thu, 08 Sep 2005 17:47:57 -0400, Robert Gamble wrote:
                    >[color=green]
                    > > On Thu, 08 Sep 2005 17:13:26 +0000, Walter Roberson wrote:[/color]
                    >
                    > ...
                    >[color=green][color=darkred]
                    > >> Answering your first question: The C89 standard does not offer any
                    > >> mechanism to "skip" values or convert them out of order.[/color]
                    > >
                    > > There is no way to do this in C99 either. In fact, I don't even think
                    > > it would be possible to design a version that did do this with the current
                    > > stdarg facility since it would need to know the type of the value being
                    > > skipped to access arguments after it.[/color]
                    >
                    > It would be easy enough to skip values using a mechanism similar to
                    > scanf()'s * assignment suppression flag. The conversion specifier would
                    > still determine the type of the corresponding argument.[/color]

                    Right, the type would be required to do this, that was the whole point.
                    I was referring to a mechanism to "skip the next n aguments" without
                    providing any other information about them.

                    Robert Gamble

                    Comment

                    • John Devereux

                      #11
                      Re: skipping parameters with printf

                      "Robert Gamble" <rgamble99@gmai l.com> writes:
                      [color=blue]
                      > Lawrence Kirby wrote:[color=green]
                      > > On Thu, 08 Sep 2005 17:47:57 -0400, Robert Gamble wrote:
                      > >[color=darkred]
                      > > > On Thu, 08 Sep 2005 17:13:26 +0000, Walter Roberson wrote:[/color]
                      > >
                      > > ...
                      > >[color=darkred]
                      > > >> Answering your first question: The C89 standard does not offer
                      > > >> any mechanism to "skip" values or convert them out of order.
                      > > >
                      > > > There is no way to do this in C99 either. In fact, I don't even
                      > > > think it would be possible to design a version that did do this
                      > > > with the current stdarg facility since it would need to know the
                      > > > type of the value being skipped to access arguments after it.[/color]
                      > >
                      > > It would be easy enough to skip values using a mechanism similar
                      > > to scanf()'s * assignment suppression flag. The conversion
                      > > specifier would still determine the type of the corresponding
                      > > argument.[/color]
                      >
                      > Right, the type would be required to do this, that was the whole
                      > point. I was referring to a mechanism to "skip the next n aguments"
                      > without providing any other information about them.[/color]

                      It was indeed the scanf suppression flag that made me think it might
                      be worth asking about a printf equivalent.


                      --

                      John Devereux

                      Comment

                      • Peter Shaggy Haywood

                        #12
                        Re: skipping parameters with printf

                        Groovy hepcat Robert Gamble was jivin' on Thu, 08 Sep 2005 17:47:57
                        -0400 in comp.lang.c.
                        Re: skipping parameters with printf's a cool scene! Dig it!
                        [color=blue]
                        >On Thu, 08 Sep 2005 17:13:26 +0000, Walter Roberson wrote:
                        >[color=green]
                        >> In article <87psrjsdsu.fsf @cordelia.dever eux.me.uk>,
                        >> John Devereux <jdREMOVE@THISd evereux.me.uk> wrote:[color=darkred]
                        >>>I would like to know if their is a conversion specifier, or other
                        >>>method, that will allow me to not use particular arguments to printf.[/color]
                        >>[color=darkred]
                        >>>Failing that, is it permissable to simply "not use" the parameter if
                        >>>it is at the end of the parameter list?[/color]
                        >>[color=darkred]
                        >>>For example,[/color]
                        >>[color=darkred]
                        >>> printf("%02d:%0 2d:%02d", hours, minutes, seconds); /* 11:59:00 */
                        >>> printf("%02d:%0 2d", hours, minutes, seconds); /* 11:59 */[/color]
                        >>
                        >> Answering your second question: when printf() and kin reach the
                        >> end of the conversion specification, they stop attempting to convert
                        >> values, so your second example will be fine.
                        >>
                        >> Answering your first question: The C89 standard does not offer any
                        >> mechanism to "skip" values or convert them out of order.[/color]
                        >
                        >There is no way to do this in C99 either. In fact, I don't even think
                        >it would be possible to design a version that did do this with the current
                        >stdarg facility since it would need to know the type of the value being
                        >skipped to access arguments after it.[/color]

                        Sure, it could be easily done. You just have to allow a display
                        suppression flag in the conversion specifier; much like scanf()'s
                        assignment suppression flag. Then the format string would simply have
                        a conversion specifier with this flag coresponding to the argument to
                        be ignored. Simple!
                        Simple example:

                        #include <stdio.h>
                        #include <stdarg.h>

                        void prints(const char *fmt, ...)
                        {
                        va_list arg;
                        const char *p;
                        FILE *fp = stdout;

                        va_start(arg, fmt);

                        for(p = fmt; *p; p++)
                        {
                        if('%' == *p)
                        {
                        /* We have a conversion specifier. */
                        int ignore = 0;
                        const char *sarg;
                        int iarg;

                        p++;
                        if('!' == *p)
                        {
                        /* Flag to ignore coresponding argument. */
                        ignore = 1;
                        p++;
                        }

                        switch(*p)
                        {
                        case 's': /* string */
                        sarg = va_arg(arg, const char *);
                        if(!ignore)
                        {
                        ignore = 0;
                        fputs(sarg, fp);
                        }
                        break;

                        case 'd': /* int */
                        iarg = va_arg(arg, int);
                        if(!ignore)
                        {
                        ignore = 0;
                        fprintf(fp, "%d", iarg);
                        }
                        break;
                        }
                        }
                        else
                        {
                        fputc(*p, fp);
                        }
                        }

                        va_end(arg);
                        }

                        int main(void)
                        {
                        prints("%s %!s %s\n", "foo", "bar", "baz");
                        prints("%d %d %!d %d\n", 1, 2, 3, 4);
                        return 0;
                        }

                        Here the simplified printf-like function, prints(), understands two
                        different types of conversion specifiers; one for a string and one for
                        an int. If the ! flag is used, the coresponding argument will be
                        ignored.
                        This program prints the following output:

                        foo baz
                        1 2 4

                        --

                        Dig the even newer still, yet more improved, sig!


                        "Ain't I'm a dog?" - Ronny Self, Ain't I'm a Dog, written by G. Sherry & W. Walker.
                        I know it's not "technicall y correct" English; but since when was rock & roll "technicall y correct"?

                        Comment

                        • Robert Gamble

                          #13
                          Re: skipping parameters with printf

                          On Sun, 11 Sep 2005 01:29:07 +0000, Peter "Shaggy" Haywood wrote:
                          [color=blue]
                          > Groovy hepcat Robert Gamble was jivin' on Thu, 08 Sep 2005 17:47:57
                          > -0400 in comp.lang.c.
                          > Re: skipping parameters with printf's a cool scene! Dig it!
                          >[color=green]
                          >>On Thu, 08 Sep 2005 17:13:26 +0000, Walter Roberson wrote:
                          >>[color=darkred]
                          >>> In article <87psrjsdsu.fsf @cordelia.dever eux.me.uk>,
                          >>> John Devereux <jdREMOVE@THISd evereux.me.uk> wrote:
                          >>>>I would like to know if their is a conversion specifier, or other
                          >>>>method, that will allow me to not use particular arguments to printf.
                          >>>
                          >>>>Failing that, is it permissable to simply "not use" the parameter if
                          >>>>it is at the end of the parameter list?
                          >>>
                          >>>>For example,
                          >>>
                          >>>> printf("%02d:%0 2d:%02d", hours, minutes, seconds); /* 11:59:00 */
                          >>>> printf("%02d:%0 2d", hours, minutes, seconds); /* 11:59 */
                          >>>
                          >>> Answering your second question: when printf() and kin reach the
                          >>> end of the conversion specification, they stop attempting to convert
                          >>> values, so your second example will be fine.
                          >>>
                          >>> Answering your first question: The C89 standard does not offer any
                          >>> mechanism to "skip" values or convert them out of order.[/color]
                          >>
                          >>There is no way to do this in C99 either. In fact, I don't even think
                          >>it would be possible to design a version that did do this with the current
                          >>stdarg facility since it would need to know the type of the value being
                          >>skipped to access arguments after it.[/color]
                          >
                          > Sure, it could be easily done. You just have to allow a display
                          > suppression flag in the conversion specifier; much like scanf()'s
                          > assignment suppression flag. Then the format string would simply have
                          > a conversion specifier with this flag coresponding to the argument to
                          > be ignored. Simple![/color]

                          I meant that this could not be done without providing the type of argument
                          being skipped. Apparently this was not well-articulated, sorry.

                          Robert Gamble

                          Comment

                          Working...