Need an explanation

J

jacob navia

Hi

I am writing this tutorial stuff again in the holidays and I came across
this problem:

The "width" field in printf is a minimum width. Printf will not truncate
a field. for instance:
#include <stdio.h>
int main(void)
{
printf("%5s %03d\n","1234567890",12345);
}

will print
1234567890 12345
and NOT
12345 123
as expected.

-------------------

OK, but how can I EXPLAIN this stuff? Is there any reason?
And no, "compatibility with previous bugs" is NOT an explanation
at least for me, and not for a beginner.

What could I say here?

Thanks
 
G

Gordon Burditt

I am writing this tutorial stuff again in the holidays and I came across
this problem:

The "width" field in printf is a minimum width. Printf will not truncate
a field. for instance:
#include <stdio.h>
int main(void)
{
printf("%5s %03d\n","1234567890",12345);
}

will print
1234567890 12345
and NOT
12345 123
as expected.

I suggest serious repair of your expecter is needed.

Pretty, lined-up output is not as important as getting the value
right. It's not like the output is going on punch cards where
everything has to start in the right column. If one of those values
was on your paycheck, which would YOU want?
And no, "compatibility with previous bugs" is NOT an explanation
at least for me, and not for a beginner.

Would you like to mention a deliberate INcompatability with
FORTRAN, which filled up fields that didn't fit with a row of *'s?
What could I say here?

If you want to print a different number, calculate a different
number. For example, n/100 or n%1000 might be the number you want
to print.
 
J

jacob navia

Gordon Burditt a écrit :
I suggest serious repair of your expecter is needed.



Pretty, lined-up output is not as important as getting the value
right. It's not like the output is going on punch cards where
everything has to start in the right column. If one of those values
was on your paycheck, which would YOU want?

The problem is that it is impossible to cut the output of a %s
to avoid a buffer oevrflow. This has led to serious problems in software
where people forgot this misfeature.

Would you like to mention a deliberate INcompatability with
FORTRAN, which filled up fields that didn't fit with a row of *'s?

That would have been a much better approach.

OK, no explanation then?

Because all you say is actually:

"It is like that, Swallow it or use Fortran".

I mean I would like to *explain* stuff, offer some
*reason* for language decisions like this.

Thanks for your answer.
 
R

Richard Tobin

jacob navia said:
The "width" field in printf is a minimum width. Printf will not truncate
a field. for instance:
#include <stdio.h>
int main(void)
{
printf("%5s %03d\n","1234567890",12345);
}

will print
1234567890 12345
and NOT
12345 123
as expected.

-------------------

OK, but how can I EXPLAIN this stuff? Is there any reason?
And no, "compatibility with previous bugs" is NOT an explanation
at least for me, and not for a beginner.

The field width is intended to be a width that will display the data
correctly and neatly. If the data doesn't fit in the field, it's
probably neatness you want to sacrifice rather than correctness.

The precision is slightly harder to explain, because it does different
things for each type, but the general idea is how much of the data to
display.

So the precision determines how the value is formatted, and the field
width specifies how it should be laid out, but doesn't override the
precision.

-- Richard
 
S

Spiros Bousbouras

jacob said:
Gordon Burditt a écrit :

The problem is that it is impossible to cut the output of a %s
to avoid a buffer oevrflow. This has led to serious problems in software
where people forgot this misfeature.

How will a printf statement cause a buffer overflow ?
OK, no explanation then?

Because all you say is actually:

"It is like that, Swallow it or use Fortran".

No , he said:

Gordon said:
Pretty, lined-up output is not as important as getting the value
right. It's not like the output is going on punch cards where
everything has to start in the right column. If one of those values
was on your paycheck, which would YOU want?

Sounds like a fine explanation to me. If it's not obvious
try answering his question:

*** If one of those values
*** was on your paycheck,
*** which would YOU want?
 
R

Richard Heathfield

jacob navia said:

The problem is that it is impossible to cut the output of a %s
to avoid a buffer oevrflow.

No, it isn't. I suggest you read the Standard's documentation on *printf
precision, or K&R2 page 244, more closely.

<snip>
 
R

Richard Tobin

jacob navia said:
The problem is that it is impossible to cut the output of a %s
to avoid a buffer oevrflow. This has led to serious problems in software
where people forgot this misfeature.

You mean where people forgot the precision part of the format?

Which is also useful for printing non-nul-terminated strings, as I may
have mentioned before :)

-- Richard
 
D

Dik T. Winter

> The "width" field in printf is a minimum width. Printf will not truncate
> a field. for instance:
> #include <stdio.h>
> int main(void)
> {
> printf("%5s %03d\n","1234567890",12345);
> }
>
> will print
> 1234567890 12345
> and NOT
> 12345 123
> as expected.

I would expect (if I had not read the standard) either:
67890 345
or
***** ***
Why do you think your expectations are better? Why do you think that
printing 12345 in three digits as an integer should give 123? It just
does not fit. Apparently you have problems with the concept of
"minimal field width". For the string you can also specify whether
the width is also maximal. I do not think you can do so for the
integer, as any number printed with fewer digits than five is not
really represenative of the number. But you should look at Fortran
when you wish to have exact widths. In that case the output would
be: 12345 ***
 
J

jacob navia

jacob navia a écrit :
Hi

I am writing this tutorial stuff again in the holidays and I came across
this problem:

The "width" field in printf is a minimum width. Printf will not truncate
a field. for instance:
#include <stdio.h>
int main(void)
{
printf("%5s %03d\n","1234567890",12345);
}

will print
1234567890 12345
and NOT
12345 123
as expected.

-------------------

OK, but how can I EXPLAIN this stuff? Is there any reason?
And no, "compatibility with previous bugs" is NOT an explanation
at least for me, and not for a beginner.

What could I say here?

Thanks

OK Thanks to all that answered. It was my fault. Actually the width is
not significative but the precision part. With the precision part
you *can* specify a maximum number of chars to be shown/printed.


Have a nice holidays.
 
J

jacob navia

Richard Heathfield a écrit :
jacob navia said:




No, it isn't. I suggest you read the Standard's documentation on *printf
precision, or K&R2 page 244, more closely.

<snip>

That's right. The problem is that the "width" field has a
wrong name. You would think it gives the width of the field
but it doesn't.
 
E

Eric Sosman

jacob said:
[...]
The problem is that it is impossible to cut the output of a %s
to avoid a buffer oevrflow. This has led to serious problems in software
where people forgot this misfeature.

Consider using the precision specifier instead of (or
in addition to) the width specifier. Subtle point: When you
use a precision with "%s", the corresponding argument must
still be a char* but need not point to a string. This comes
in handy when dealing with "counted strings" that are not
"strings" in C's sense.
I mean I would like to *explain* stuff, offer some
*reason* for language decisions like this.

Unless you can track down the people who thought up the
original ancestral printf() and ask them directly, this will
necessarily involve a certain amount of guesswork.
 
R

Richard Heathfield

jacob navia said:
Richard Heathfield a écrit :

That's right. The problem is that the "width" field has a
wrong name. You would think it gives the width of the field
but it doesn't.

The Standard describes the relevant value as specifying a "minimum field
width". This seems to me to be a correct description. If you think it's
wrong, take it up with ISO.
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,756
Messages
2,569,535
Members
45,008
Latest member
obedient dusk

Latest Threads

Top