Le 30/11/10 17:57, James Kanze a écrit :
No. It doesn't work because you don't dynamically scale the
buffer according to the format string and the type of number.
Thisis not necessary. Just use a buffer of size 30 and you will
be safe even in 64 bit environments with 64 bit ints...
But obviously, whymake it simple when you can make it more
and more obscure.
It doesn't work because you can change the format string and the
type of the number without changing the size of the buffer.
See above.
it
doesn't work because, fundamentally, you have no real means of
knowing how big the buffer has to be.
If you assume 64 bit numbers, the decimal representation of a
64 bit number can't exceed 20 digits. That's very simple
math... By using a 30 bytebuffer you are 100 % SURE that
it will ALWAYS work. Yes, in 10 years you *could* have
128 bit numbers but I doubt that they would be just
ints". Besides, "ints" have stayed 32 bits in all machines
that I have seen.
(Actually, your precise
example doesn't work because it always outputs "+04d", rather
than number. A simple typo. But its sensitivity to such things
is precisely why sprintf is not something a professional would
use in production code.)
I posted a working example without any typo that you do not mention.
In some cases, you can do something like:
char buffer[6];
assert(number< 1000&& number> -1000);
sprintf(buffer, "%+04d", number);
In others, you can allocate the buffer dynamically, or at least
with the size determined by some compile time expression, so
that at least you don't get bit the day someone changes the type
(or you upgrade to 64 bit machine), but you're still at the
mercy of someone modifying the format.
If you insist on saving 24 bytes local variable space... that
could happen to you.
And if somebody modifies the format without modifying the buffer
he (she) introduces a bug, and you can't do anything about that.
But if you develop your own awfully complicated solution you expose
yourself to MORE potential problems...
Look at this:
ostream& operator<<(ostream &os, tstClass &t1)
{
char sign = (t1.i<0)?'-':'+';
int ii = (t1.i<0)?-(t1.i)
t1.i);
os << "Integer in " << tstClass::width << " width and Sign is: {" <<
sign << setw(tstClass::width) << setfill('0') << ii << "}" << endl;
return(os);
}
Note that you set the output width to 6. Now you have introduced a bug
in some OTHER procedure that had set the width to 9 several functions
before and that now it will output an INCORRECT result, truncated
to 6 places.
The same with the other parameters. As far as I know, there is no way to
save the values of those global parameters and restore them to their
original values, what is one of the BIGGEST problems in your approach.
Care to answer why you did not see that OBVIOUS BUG?
jacob navia