Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

How to print floats with leading blanks instead of leading zeros using sprintf?

1,817 views
Skip to first unread message

Валерий Симонов

unread,
May 28, 2012, 11:09:25 AM5/28/12
to
Hi everyone,

I want to specify labels for the plots using sprintf.
According to http://www.cplusplus.com/reference/clibrary/cstdio/sprintf/
sprintf(' %3.0f',1) should print "001"
sprintf(' %3.0d',1) should print " 1".
However gnuplot outputs:
sprintf(' %3.0f',1) "001"
sprintf(' %3.0d',1) "1" (without leading blanks).

Does anyone know how to fix this issue?

Thanks in advance!

Regards,
Valera

sfeam

unread,
May 28, 2012, 2:16:26 PM5/28/12
to
I cannot reproduce either of those results here.
The first one in particular makes no sense.
Could it be that you are not really using the format you show us?

gnuplot> print sprintf("|%3.0d|",1)
| 1|
gnuplot>

Hans-Bernhard Bröker

unread,
May 28, 2012, 5:32:58 PM5/28/12
to
On 28.05.2012 17:09, Валерий Симонов wrote:

> I want to specify labels for the plots using sprintf.
> According to http://www.cplusplus.com/reference/clibrary/cstdio/sprintf/
> sprintf(' %3.0f',1) should print "001"
> sprintf(' %3.0d',1) should print " 1".

That reference (or your understanding of it) is incorrect, as far as the
behaviour of the 'f' format specifier is concerned.

> However gnuplot outputs:
> sprintf(' %3.0f',1) "001"

No, it doesn't.

> sprintf(' %3.0d',1) "1" (without leading blanks).

> Does anyone know how to fix this issue?

What issue, in particular?

How come your subject line is about blanks in printing _floats_, but
then you only try syntax that you think you should print leading blanks
in _integers_?

valera...@gmail.com

unread,
May 28, 2012, 10:56:58 PM5/28/12
to
Thank you for your reply.

You are right sprintf(' %03.0f',1) should print "001" (not sprintf(' %3.0f',1)).
Do you agree it makes sense?

What I want to print is " 1". Do you know how this task can be accomplished?

About integers you are right again. But doesn't (although with warnings) C transform int to float when necessary?
Message has been deleted

valera...@gmail.com

unread,
May 28, 2012, 11:19:58 PM5/28/12
to sf...@users.sourceforge.net
sfeam, thank you for your reply.

I will provide some more details.

I want to plot the file:
"sprintf.txt"
0.2 1.5970E-01 1.1262E-01
0.4 5.7188E-01 2.2227E-01
0.6 2.2019E-01 4.3648E-01

executing the following script: ./plot_sprintf 20 1
#!/bin/sh
gnuplot << EOF
set terminal postscript eps enhanced
set output 'plot_sprintf.eps'
plot "sprintf.txt" using (\$1):(\$2) w l ls 1 t sprintf('T > %03.0f abc',$1),\
"sprintf.txt" using (\$1):(\$3) w l ls 2 t sprintf('T > %3d abc',$2)
unset table
EOF

After the script execution I get an eps file with the following strings that "don't align properly": they look approximately like this
T > 020 abc
T > 1 abc
instead of looking like this (the way I want):
T > 020 abc
T > 1 abc.

As Hans-Bernhard mentioned I used %d specifier for printing a float, which is of course wrong. Actually all the "floats" I provide for sprintf can be converted into integers (so these floats are 20.0 and 1.0 in the above example). I used %d because I started trial and error method just to get what I want.

P.S.
In the reference it was written:
"Minimum number of characters to be printed. If the value to be printed is shorter than this number, the result is padded with blank spaces. The value is not truncated even if the result is larger."
So specifying sprintf('T > %3.0f abc', 1) I expected to see desired blanks, but I didn't. Than I started applying "everything you can try" method.
By the way sprintf('T > %3.0f abc', 1) did the same job as sprintf('T > %3d abc', 1). However sprintf('T > %5d abc', 1) had the desired output form
T > 020 abc
T > 1 abc
but only for 1 digit numbers.

Sorry, I did a pretty bad job writing my first post.

sfeam

unread,
May 28, 2012, 11:48:45 PM5/28/12
to
Валерий Симонов wrote:

> #!/bin/sh
> gnuplot << EOF
> set terminal postscript eps enhanced

Since you have not specified a font, the program will use Helvetica
by default. But Helvetica is a proportionally-spaced font,
which means that adding a fixed number of spaces will never line
things up the way you want.
You would have to use Courier or some other fixed-width font.

> plot "sprintf.txt" using (\$1):(\$2) w l ls 1 \
> t sprintf('T > %03.0f abc',$1)

That command makes no sense.
First problem:
'using (\$1)'
will cause an error "illegal character". I guess you just mean
'using 1:2'
Second problem:
You cannot give a title that depends on $1, because the title
is not something that is re-calculated for every line of data.
The program will complain "undefined value". I don't know
what you are trying to do, but this command will not work.

Ethan

Christoph Bersch

unread,
May 29, 2012, 3:51:20 AM5/29/12
to
On 28.05.2012 17:09, Валерий Симонов wrote:
> Hi everyone,
>
> I want to specify labels for the plots using sprintf.
> According to http://www.cplusplus.com/reference/clibrary/cstdio/sprintf/
> sprintf(' %3.0f',1) should print "001"
> sprintf(' %3.0d',1) should print " 1".

sprintf('% 3d', 1)

Christoph

valera...@gmail.com

unread,
May 29, 2012, 9:19:49 AM5/29/12
to
Christoph, thanks!

valera...@gmail.com

unread,
May 29, 2012, 9:18:33 AM5/29/12
to sf...@users.sourceforge.net
Ethan, thanks a lot! You were right: specifying Courier solved the problem.

> First problem:
> 'using (\$1)'
> will cause an error "illegal character". I guess you just mean
> 'using 1:2'
> Second problem:
> You cannot give a title that depends on $1, because the title
> is not something that is re-calculated for every line of data.
> The program will complain "undefined value". I don't know
> what you are trying to do, but this command will not work.

I provided the exact code I execute. So this piece of code works at least for me.

As far as I understand it works because it is a piece of code in bash. Thus when bash executes the script it will execute this piece "using (\$1)" in gnuplot as "using ($1)". The $1 for bash is the first argument of the script. As I ran the script with "./plot_sprintf 20 1", the first argument is 20. Thus bash will read the following line:
plot "sprintf.txt" using (\$1):(\$2) w l ls 1 t sprintf('T > %03.0f abc',$1)
but will execute the following line in gnuplot:
plot "sprintf.txt" using ($1):($2) w l ls 1 t sprintf('T > %03.0f abc',20)

Ethan, once again thanks, you solved my problem.

Hans-Bernhard Bröker

unread,
May 29, 2012, 12:33:00 PM5/29/12
to
On 29.05.2012 04:56, valera...@gmail.com wrote:

[...]
>>> However gnuplot outputs: sprintf(' %3.0f',1) "001"

>> No, it doesn't.
[...]
> What I want to print is " 1". Do you know how this task can be
> accomplished?

You already knew yourself --- the command you tried did (pretty much)
exactly that. You just misinterpreted the actual result you saw because
you looked at it in a proportional-font output format.

> About integers you are right again. But doesn't (although with
> warnings) C transform int to float when necessary?

Not in these cases it wouldn't. Variadic functions don't give the
compiler the information to apply such transformations automatically.
So if you tried a stunt like printf("5.3f", 3) in a C program, you
would be giving the compiler and/or compiled program a legit excuse to
do whatever it pleases (the technical term is "undefined behaviour").

But that's rather beside the point, since you're using gnuplot here, not
C. Yes, gnuplot is designed to imitate C, but the analogy cannot be
perfect. gnuplot will convert automatically from float to integer and
vice versa, both without a warning. It can do that because unlike C it
has information about the type of things even at run time.

valera...@gmail.com

unread,
May 31, 2012, 8:43:39 AM5/31/12
to
Hans-Bernhard Bröker, thank you for your reply and elucidations!
0 new messages