f



Use case for %n in printf() call?

%n returns the number of characters so far, but I can't see how this would
%be useful.  That is, you can do:

printf("test %n bar\n",&x);

and get x set to 5.  But I'm at a loss as to how this could be used.

ISTM that the most common use of this would be to affect the width of
another (i.e., subsequent) formatting string in the same printf(), but
doing that would probably run afoul of the gods of UB.

Note that you can always get the total number of characters printed by the
printf() call by using the return value of printf() itself.

So, when/how would you be able to use the intermediate value returned by %n?

-- 
If it seems like I'm not responding to some moronic criticism that you've
posted in response to one of my posts, be aware that I do not debate with idiots.

It doesn't mean you've won anything...
0
gazelle
11/28/2016 10:20:36 PM
comp.unix.programmer 10848 articles. 0 followers. kokososo56 (350) is leader. Post Follow

7 Replies
576 Views

Similar Articles

[PageSpeed] 26

On 2016-11-28, Kenny McCormack <gazelle@shell.xmission.com> wrote:
> %n returns the number of characters so far, but I can't see how this would
> %be useful.  That is, you can do:
>
> printf("test %n bar\n",&x);
>
> and get x set to 5.  But I'm at a loss as to how this could be used.

Let's get creative:

#include <stdio.h>

int main(void)
{
  const char *whatever = "foo";
  int tab_position;

  printf("%s test %nbar\n", whatever, &tab_position);
  printf("%*stabbed-over\n", tab_position, "");
}

Output:

foo test bar
         tabbed-over


Other uses might be trailing dynamic field widths inferred from the first line.
0
Kaz
11/29/2016 6:25:14 AM
In article <20161128221611.715@kylheku.com>,
Kaz Kylheku  <221-501-9011@kylheku.com> wrote:
>On 2016-11-28, Kenny McCormack <gazelle@shell.xmission.com> wrote:
>> %n returns the number of characters so far, but I can't see how this would
>> %be useful.  That is, you can do:
>>
>> printf("test %n bar\n",&x);
>>
>> and get x set to 5.  But I'm at a loss as to how this could be used.
>
>Let's get creative:
>
>#include <stdio.h>
>
>int main(void)
>{
>  const char *whatever = "foo";
>  int tab_position;
>
>  printf("%s test %nbar\n", whatever, &tab_position);
>  printf("%*stabbed-over\n", tab_position, "");
>}
>
>Output:
>
>foo test bar
>         tabbed-over
>
>
>Other uses might be trailing dynamic field widths inferred from the first
>line.

Well, in the general spirit of many of these newsgroups, where people say
that new features should never be added if it is possible (however
clumsily) to do what you want to do already (with existing features), it
should be noted that you can always do the equivalent of %n just by
breaking up your printfs into multiple calls.  I.e., your example becomes:

  tab_position = printf("%s test ", whatever);
  printf("bar\n");
  printf("%*stabbed-over\n", tab_position, "");

So, a language purist would argue that %n is superfluous, as long as we can
use and rely upon the return value of printf().

-- 
Donald Drumpf claims to be "the least racist person you'll ever meet".

This would be true if the only other person you've ever met was David Duke.
0
gazelle
11/29/2016 12:59:43 PM
In article <o1ju3v$qj1$1@news.xmission.com>,
 gazelle@shell.xmission.com (Kenny McCormack) wrote:

> >  printf("%s test %nbar\n", whatever, &tab_position);
> >  printf("%*stabbed-over\n", tab_position, "");
> >}
> >
> >Output:
> >
> >foo test bar
> >         tabbed-over
> >
> >
> >Other uses might be trailing dynamic field widths inferred from the first
> >line.
> 
> Well, in the general spirit of many of these newsgroups, where people say
> that new features should never be added if it is possible (however
> clumsily) to do what you want to do already (with existing features), it
> should be noted that you can always do the equivalent of %n just by
> breaking up your printfs into multiple calls.  I.e., your example becomes:
> 
>   tab_position = printf("%s test ", whatever);
>   printf("bar\n");
>   printf("%*stabbed-over\n", tab_position, "");
> 
> So, a language purist would argue that %n is superfluous, as long as we can
> use and rely upon the return value of printf().

By that logic we don't need %*, since you could construct the format 
string dynamically with sprintf().

-- 
Barry Margolin, barmar@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
0
Barry
11/29/2016 4:40:34 PM
On Mon, 28 Nov 2016 22:20:36 +0000, Kenny McCormack wrote:

> ISTM that the most common use of this would be to affect the width of
> another (i.e., subsequent) formatting string in the same printf(), but
> doing that would probably run afoul of the gods of UB.

Valid use would be to affect the position or width of an element
in some later printf(), e.g. if you're trying to make stuff align.

I can imagine that there are situations where it might be non-trivial to
figure out exactly how many characters would result from a particular
conversion, whereas it's trivial for *printf() itself to keep track of
that information.

The width of numeric conversions can vary depending upon the value
(whether to include a negative sign or a decimal point, whether the
exponent is 2 or 3 digits).

Locales may also be a factor, although getting stuff to align is
complicated (if not eliminated altogether) by multi-byte encodings and
half-width/full-width characters, meaning that the number of "characters"
according to *printf isn't necessarily the same as the number of display
columns.

0
Nobody
12/1/2016 2:30:03 AM
In a quick scan of open source software lying on hand I found no uses of %n=
 with the printf() family but a (single) use of %n with sscanf() in the Tcl=
 source, where it's used to check that the entire string was parsed:
    i =3D sscanf(mode, "%d,%c,%d,%d%n", speedPtr, &parity, dataPtr,
            stopPtr, &end);
    if ((i !=3D 4) || (mode[end] !=3D '\0')) {
        error handling here...

I thought I had seen a use of %n with printf() but I guess not...

(half off-topic: OpenBSD's libc supports %n but (a) the kernel's version of=
 printf() purposely doesn't, and (b) the libc source has preprocessor check=
s to disable support for %n in printf which were requested by Google for th=
e Android libc, so unless something has changed in the last 2.5 years or so=
 Android's libc does _not_ support %n with printf())


Philip Guenther
0
Philip
12/1/2016 5:25:23 AM
Barry Margolin , dans le message
<barmar-040601.11400729112016@88-209-239-213.giganet.hu>, a �crit�:
>> Well, in the general spirit of many of these newsgroups, where people say
>> that new features should never be added if it is possible (however
>> clumsily) to do what you want to do already

> By that logic we don't need %*, since you could construct the format 
> string dynamically with sprintf().

By that logic, printf() would not exist at all.
0
Nicolas
12/1/2016 10:12:21 AM
On Wed, 30 Nov 2016 21:25:23 -0800 (PST)
Philip Guenther <guenther@gmail.com> wrote:

> I found no uses of %n with the printf() family but a (single) use of 
> %n with sscanf() in the Tcl source

I would venture to say that any problem with fancy output requirements
is unlikely these days to be implemented in C, especially in open
source.  From that point of view, %n is anachronistic: it solves a
problem that no longer exists.  

(I'm not saying no one uses printf.  I'm saying by the time you're at
the point that %n is useful, you're probably using Python or the like.
Or C++.) 

OTOH just the other day I used %n with scanf.  I belong to a School
of One that views as malignent the hydra-headed versions of strtod.
How many ways can there be to convert a string to a double?  scanf
works perfectly well if you check that it returns 1 and (with %n) that
it scanned the whole string.  If scanf didn't have so many specialized
alternatives, %n would probably see more use.  

--jkl


0
James
12/2/2016 1:58:08 AM
Reply: