skipping parameters with printf

Discussion in 'C Programming' started by John Devereux, Sep 8, 2005.

  1. 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:%02d:%02d", hours, minutes, seconds); /* 11:59:00 */
    printf("%02d:%02d", hours, minutes, seconds); /* 11:59 */


    Thanks,


    --

    John Devereux
    John Devereux, Sep 8, 2005
    #1
    1. Advertising

  2. In article <>,
    John Devereux <> 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:%02d:%02d", hours, minutes, seconds); /* 11:59:00 */
    > printf("%02d:%02d", 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.

    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.
    Walter Roberson, Sep 8, 2005
    #2
    1. Advertising

  3. John Devereux <> 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:%02d:%02d", hours, minutes, seconds); /* 11:59:00 */
    > printf("%02d:%02d", hours, minutes, seconds); /* 11:59 */


    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 ()
    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.
    Irrwahn Grausewitz, Sep 8, 2005
    #3
  4. On Thu, 08 Sep 2005 17:13:26 +0000, Walter Roberson wrote:

    > In article <>,
    > John Devereux <> 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:%02d:%02d", hours, minutes, seconds); /* 11:59:00 */
    >> printf("%02d:%02d", 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.


    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.

    > 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.


    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
    Robert Gamble, Sep 8, 2005
    #4
  5. In article <>,
    John Devereux <> wrote:
    >
    >
    > printf("%02d:%02d:%02d", hours, minutes, seconds); /* 11:59:00 */
    > printf("%02d:%02d", hours, minutes, seconds); /* 11:59 */


    Have you considered strftime()?
    Anonymous 7843, Sep 8, 2005
    #5
  6. In article <>,
    Robert Gamble <> wrote:
    >On Thu, 08 Sep 2005 17:13:26 +0000, Walter Roberson wrote:


    >> 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.


    >I am pretty sure the $n feature is part of the Posix standard so it is
    >portable systems implementing Posix.



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


    >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.


    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
    Walter Roberson, Sep 8, 2005
    #6
  7. On Thu, 08 Sep 2005 22:10:04 +0000, Walter Roberson wrote:

    > In article <>, Robert Gamble
    > <> wrote:
    >>On Thu, 08 Sep 2005 17:13:26 +0000, Walter Roberson wrote:

    >
    >>> 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.

    >
    >>I am pretty sure the $n feature is part of the Posix standard so it is
    >>portable systems implementing Posix.

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


    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.

    >>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.

    >
    > 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.


    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
    Robert Gamble, Sep 9, 2005
    #7
  8. (Anonymous 7843) writes:

    > In article <>,
    > John Devereux <> wrote:
    > >
    > >
    > > printf("%02d:%02d:%02d", hours, minutes, seconds); /* 11:59:00 */
    > > printf("%02d:%02d", hours, minutes, seconds); /* 11:59 */

    >
    > Have you considered strftime()?


    I probably should have...

    Thanks all for the help.

    --

    John Devereux
    John Devereux, Sep 9, 2005
    #8
  9. On Thu, 08 Sep 2005 17:47:57 -0400, Robert Gamble wrote:

    > On Thu, 08 Sep 2005 17:13:26 +0000, Walter Roberson wrote:


    ....

    >> 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.


    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
    Lawrence Kirby, Sep 9, 2005
    #9
  10. Lawrence Kirby wrote:
    > On Thu, 08 Sep 2005 17:47:57 -0400, Robert Gamble wrote:
    >
    > > On Thu, 08 Sep 2005 17:13:26 +0000, Walter Roberson wrote:

    >
    > ...
    >
    > >> 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.

    >
    > 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.


    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
    Robert Gamble, Sep 9, 2005
    #10
  11. "Robert Gamble" <> writes:

    > Lawrence Kirby wrote:
    > > On Thu, 08 Sep 2005 17:47:57 -0400, Robert Gamble wrote:
    > >
    > > > On Thu, 08 Sep 2005 17:13:26 +0000, Walter Roberson wrote:

    > >
    > > ...
    > >
    > > >> 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.

    > >
    > > 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.

    >
    > 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.


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


    --

    John Devereux
    John Devereux, Sep 9, 2005
    #11
  12. 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!

    >On Thu, 08 Sep 2005 17:13:26 +0000, Walter Roberson wrote:
    >
    >> In article <>,
    >> John Devereux <> 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:%02d:%02d", hours, minutes, seconds); /* 11:59:00 */
    >>> printf("%02d:%02d", 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.

    >
    >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.


    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!

    http://alphalink.com.au/~phaywood/
    "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 "technically correct" English; but since when was rock & roll "technically correct"?
    Peter Shaggy Haywood, Sep 11, 2005
    #12
  13. On Sun, 11 Sep 2005 01:29:07 +0000, Peter "Shaggy" Haywood wrote:

    > 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!
    >
    >>On Thu, 08 Sep 2005 17:13:26 +0000, Walter Roberson wrote:
    >>
    >>> In article <>,
    >>> John Devereux <> 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:%02d:%02d", hours, minutes, seconds); /* 11:59:00 */
    >>>> printf("%02d:%02d", 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.

    >>
    >>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.

    >
    > 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!


    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
    Robert Gamble, Sep 11, 2005
    #13
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. ben
    Replies:
    4
    Views:
    612
    Martin Ambuhl
    Jun 26, 2004
  2. whatluo

    (void) printf vs printf

    whatluo, May 26, 2005, in forum: C Programming
    Replies:
    29
    Views:
    1,238
  3. pozz

    Skipping parameters in a printf()

    pozz, May 2, 2007, in forum: C Programming
    Replies:
    13
    Views:
    986
  4. kito
    Replies:
    2
    Views:
    413
  5. azza

    printf affects following printf/s

    azza, Oct 17, 2010, in forum: C Programming
    Replies:
    0
    Views:
    431
Loading...

Share This Page