468,753 Members | 1,181 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 468,753 developers. It's quick & easy.

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

John Devereux
Nov 15 '05 #1
12 6749
In article <87************@cordelia.devereux.me.uk>,
John Devereux <jd******@THISdevereux.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:%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.
Nov 15 '05 #2
John Devereux <jd******@THISdevereux.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:%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 (ir*******@freenet.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.
Nov 15 '05 #3
On Thu, 08 Sep 2005 17:13:26 +0000, Walter Roberson wrote:
In article <87************@cordelia.devereux.me.uk>,
John Devereux <jd******@THISdevereux.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:%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
Nov 15 '05 #4
In article <87************@cordelia.devereux.me.uk>,
John Devereux <jd******@THISdevereux.me.uk> wrote:


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


Have you considered strftime()?
Nov 15 '05 #5
In article <pa****************************@gmail.com>,
Robert Gamble <rg*******@gmail.com> 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
Nov 15 '05 #6
On Thu, 08 Sep 2005 22:10:04 +0000, Walter Roberson wrote:
In article <pa****************************@gmail.com>, Robert Gamble
<rg*******@gmail.com> 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
Nov 15 '05 #7
an******@example.com (Anonymous 7843) writes:
In article <87************@cordelia.devereux.me.uk>,
John Devereux <jd******@THISdevereux.me.uk> 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
Nov 15 '05 #8
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
Nov 15 '05 #9
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

Nov 15 '05 #10
"Robert Gamble" <rg*******@gmail.com> 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
Nov 15 '05 #11
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 <87************@cordelia.devereux.me.uk>,
John Devereux <jd******@THISdevereux.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:%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"?
Nov 15 '05 #12
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 <87************@cordelia.devereux.me.uk>,
John Devereux <jd******@THISdevereux.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:%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
Nov 15 '05 #13

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

9 posts views Thread by Chuck Anderson | last post: by
5 posts views Thread by Peter Ammon | last post: by
7 posts views Thread by Québec | last post: by
13 posts views Thread by pozz | last post: by
11 posts views Thread by Googy | last post: by
1 post views Thread by CARIGAR | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.