473,324 Members | 2,166 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,324 software developers and data experts.

Ignore argument to 'printf'?


I have a situation where I want to use one of two different format
strings in a 'printf' call, depending on a flag set by the user.
One of the calls uses a field width modifier, and the other one doesn't.
So what I have at the moment is

if (UserFlag) {
printf("%*d. ", clue_width, clue_number);
}
else {
printf("%d.\t", clue_number);
}

What I'd like to have is

const char *clue_format = (UserFlag? "%*d. ": [...something...]);
printf(clue_format, clue_width, clue_number);

Problem is, I don't see any way to tell 'printf' to simply discard
its second argument. "%0.0d" doesn't work; according to the standard,
'printf' will never truncate its output, even given a zero field width.
So, can anyone think of what my [...something...] should be?
Failing that, can anyone think of a method shorter and cleaner than
the method outlined above?

Thanks,
-Arthur
Nov 14 '05 #1
9 7331
In article <Pi**********************************@unix49.andre w.cmu.edu>,
Arthur J. O'Dwyer <aj*@nospam.andrew.cmu.edu> wrote:
I have a situation where I want to use one of two different format
strings in a 'printf' call, depending on a flag set by the user. Problem is, I don't see any way to tell 'printf' to simply discard
its second argument.


printf() stops converting when it reaches the end of its format
string, ignoring any argument that has not been converted.

(It helps to remember printf()'s antecedants, in the days when
there was no way to tell how many arguments had been given to
a varadic call, so the only way that printf() had of knowing
there -were- more arguments was to hit another format specifier.)
--
'ignorandus (Latin): "deserving not to be known"'
-- Journal of Self-Referentialism
Nov 14 '05 #2

On Sat, 2 Apr 2005, Arthur J. O'Dwyer wrote:

I have a situation where I want to use one of two different format
strings in a 'printf' call, depending on a flag set by the user.
One of the calls uses a field width modifier, and the other one doesn't.
So what I have at the moment is

if (UserFlag) {
printf("%*d. ", clue_width, clue_number);
}
else {
printf("%d.\t", clue_number);
}


I see I've gotten two "non-answers" already. In case it wasn't
clear, I'm looking for solutions to the setup above, not to

if (UserFlag) {
printf("%*d. ", a, b);
}
else {
printf("%d.\t", a);
}

HTH,
-Arthur
Nov 14 '05 #3
[edited slightly for vertical space]

In articles <Pi**********************************@unix49.andre w.cmu.edu>
and <Pi**********************************@unix48.andre w.cmu.edu>
Arthur J. O'Dwyer <aj*@nospam.andrew.cmu.edu> wrote [both > and >>]:
... what I have at the moment is
if (UserFlag) printf("%*d. ", clue_width, clue_number);
else printf("%d.\t", clue_number);
I see I've gotten two "non-answers" already. In case it wasn't
clear, I'm looking for solutions to the setup above, not to
if (UserFlag) printf("%*d. ", a, b);
else printf("%d.\t", a);


Indeed, in this case the "ignores extra, unused arguments" feature
of printf() is not helpful, because we need the "clue_width"
argument to disappear.

There are a couple of possible approaches. One, which I will
mention just because it is horrendously ugly and nonportable but
chances are it works on your ILP32 machine, is to misuse the "%n"
conversion specifier and assume that sizeof(int) == sizeof(int *):

if (UserFlag) {
fmt = "%*d. ";
arg1 = clue_width;
} else {
fmt = "%n%d.\t";
arg1 = (int) &clue_width;
}
...
printf(fmt, arg1, clue_number);

Of course, this potentially breaks as soon as you move to an I32LP64
machine (where sizeof(int) is 4 but sizeof(int *) is 8). There
are even worse hacks to work around that, in various even-more-
machine-dependent ways, but this whole thing is a bad idea.

So what else can we do? Well, observe that printf's output for
"%d" and "%1d" is always 100% identical:

printf("(plain) d: [%d] [%d] [%d]\n", 0, 1, 99);
printf("width 1d: [%1d] [%1d] [%1d]\n", 0, 1, 99);

The output here is always "[0] [1] [99]": specifying a minimum
field width of 1 has no effect because %d always produces at least
one output character. So now the answer is obvious:

if (UserFlag) {
fmt = "%*d. ";
/* and use specified clue_width */
} else {
fmt = "%*d.\t";
clue_width = 1;
}
...
printf(fmt, arg1, clue_number);

(In fact, %*d with an integer value of -1 also works. Using 0
works in my printf, but I think the Standard does not say just
what happens in this case.)
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.
Nov 14 '05 #4
In article <Pi**********************************@unix48.andre w.cmu.edu>,
Arthur J. O'Dwyer <aj*@nospam.andrew.cmu.edu> wrote:
On Sat, 2 Apr 2005, Arthur J. O'Dwyer wrote:
if (UserFlag) {
printf("%*d. ", clue_width, clue_number);
}
else {
printf("%d.\t", clue_number);
}
I see I've gotten two "non-answers" already.


Sorry, I misread the "second argument" as "last argument".

I do not have my copy of the standard here to check the
portability of the below... I -remember- this as being part
of the standard (not just as a local extension on the system I'm
checking), but YMMV.

printf( UserFlag? "%*d. " : "%2$d.\t", clue_width, clue_number );

posp$ An optional entry, consisting of one or more decimal digits
followed by a $ character, specifying the number of the next arg to
access. The first arg (just after format) is numbered 1. If this
field is not specified, the arg following the most recently used
arg will be used.

--
Oh, to be a Blobel!
Nov 14 '05 #5
Walter Roberson wrote:

I do not have my copy of the standard here to check the
portability of the below... I -remember- this as being part
of the standard (not just as a local extension on the system I'm
checking), but YMMV.

printf( UserFlag? "%*d. " : "%2$d.\t", clue_width, clue_number );

posp$ An optional entry, consisting of one or more decimal
digits followed by a $ character,...


The $ character is not a member of the basic character set in C.
[Aside: neither is @ unfortunately.]

It may well be standardised usage, but it is not C standard usage.

--
Peter

Nov 14 '05 #6

On Sat, 2 Apr 2005, Chris Torek wrote:
Arthur J. O'Dwyer <aj*@nospam.andrew.cmu.edu> wrote [both > and >>]:
... what I have at the moment is
if (UserFlag) printf("%*d. ", clue_width, clue_number);
else printf("%d.\t", clue_number);
if (UserFlag) {
fmt = "%*d. ";
/* and use specified clue_width */
} else {
fmt = "%*d.\t";
clue_width = 1;
}
...
printf(fmt, arg1, clue_number);


...Of course! Argh! Thank you. I hadn't been thinking of modifying
'clue_width', but actually there's no reason not to.

-Arthur
Nov 14 '05 #7
Arthur J. O'Dwyer wrote:

On Sat, 2 Apr 2005, Arthur J. O'Dwyer wrote:

I have a situation where I want to use one of two different format
strings in a 'printf' call, depending on a flag set by the user.
One of the calls uses a field width modifier, and the other one doesn't.
So what I have at the moment is

if (UserFlag) {
printf("%*d. ", clue_width, clue_number);
}
else {
printf("%d.\t", clue_number);
}


I see I've gotten two "non-answers" already. [...]


What you're using seems perfectly reasonable and not
worth changing (unless surrounding context provides reasons
of its own). You could try

printf(UserFlag ? "%*d. " : "%*d\t", /* note change */
UserFlag ? clue_width : 0,
clue_number);

.... but to my eye this doesn't look like an improvement.

--
Eric Sosman
es*****@acm-dot-org.invalid
Nov 14 '05 #8
Arthur J. O'Dwyer wrote:

On Sat, 2 Apr 2005, Chris Torek wrote:
Arthur J. O'Dwyer <aj*@nospam.andrew.cmu.edu> wrote [both > and >>]:
... what I have at the moment is
if (UserFlag) printf("%*d. ", clue_width, clue_number);
else printf("%d.\t", clue_number);


if (UserFlag) {
fmt = "%*d. ";
/* and use specified clue_width */
} else {
fmt = "%*d.\t";
clue_width = 1;
}
...
printf(fmt, arg1, clue_number);

...Of course! Argh! Thank you. I hadn't been thinking of modifying
'clue_width', but actually there's no reason not to.

-Arthur


Try this..

#include <stdio.h>

int main(void) {
char *format = "%*d.\n ";
int width = 10;
int number = 23;
printf(format, width, number);
width = 0;
printf(format, width, number);
return 0;
}
--
Joe Wright mailto:jo********@comcast.net
"Everything should be made as simple as possible, but not simpler."
--- Albert Einstein ---
Nov 14 '05 #9
On 2 Apr 2005 20:54:34 GMT, ro******@ibd.nrc-cnrc.gc.ca (Walter
Roberson) wrote:
<snip>
I do not have my copy of the standard here to check the
portability of the below... I -remember- this as being part
of the standard (not just as a local extension on the system I'm
checking), but YMMV. <snip printf %position$specifier>


It's POSIX-standard (not just local) but not C-standard.

- David.Thompson1 at worldnet.att.net
Nov 14 '05 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

23
by: FrancisC | last post by:
#include <stdio.h> int file_copy( char *oldname, char *newname ); int main() { char source, destination; printf("\nEnter source file: ");
23
by: Daniel Rudy | last post by:
Hello, I'm trying to learn how command line arguments are handled in C. The following code segment that I wrote as a test program compiles, but when I try to run it, it core dumps. This is...
64
by: Morgan Cheng | last post by:
Hi All, I was taught that argument valuse is not supposed to be changed in function body. Say, below code is not good. void foo1(int x) { x ++; printf("x+1 = %d\n", x); } It should be...
17
by: Charles Sullivan | last post by:
The library function 'qsort' is declared thus: void qsort(void *base, size_t nmemb, size_t size, int(*compar)(const void *, const void *)); If in my code I write: int cmp_fcn(...); int...
2
by: john | last post by:
Hello, Supposed sizeof(short) == 2 and sizeof(int) == 4 and argument passing in a stack. When doing: int i1; int i2; printf("%d %d", i1, i2); // OK. 2 arg of size 4
5
by: shaanxxx | last post by:
i have statements printf("%f",(double)1); /* works fine although i have sent %f for double */ printf("%c",(int)64); /* works fine although i have sent %c for int */ Need your comment on...
7
by: bowlderster | last post by:
Hello,all. I want to get the array size in a function, and the array is an argument of the function. I try the following code. /*************************************** */ #include<stdio.h>...
8
by: A. Anderson | last post by:
Howdy everyone, I'm experiencing a problem with a program that I'm developing. Take a look at this stack report from GDB - #0 0xb7d782a3 in strlen () from /lib/tls/i686/cmov/libc.so.6 #1 ...
30
by: Adam | last post by:
Hi, I have a simple printf-like function: int print(const char *format, ...) { char buffer; va_list argptr; int i;
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
1
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.