int main(void) is better than int main()

J

James Kanze

o_O unknown parameters! :) I've always meant to use that at some point -
will have to have a look into the equivalent in C++.

There isn't an equivalent, and this feature has been declared
"obsolete" in C99 as well. When I started in C, it was the only
possibility to declare a function. There was no way of telling
the compiler how many parameters there were, or what their types
were. You just had to be very careful to pass the right number
and types when you called the function. (E.g. if the function
took a double, and you called it with f(0), the compiler
wouldn't complain, but it would just pass an int, and not a
double.)

Believe me, this is one feature of K&R C I definitely don't miss.
 
L

Lars Uffmann

James said:
There isn't an equivalent, and this feature has been declared
"obsolete" in C99 as well.

Oh - I was mainly thinking of functions that take any amount of
parameters like... printf, for example...
 
I

Ian Collins

Lars said:
Oh - I was mainly thinking of functions that take any amount of
parameters like... printf, for example...

Variadic functions. The same conditions James mentioned apply to these
as well!
 
R

Rolf Magnus

Lars said:
Oh - I was mainly thinking of functions that take any amount of
parameters like... printf, for example...

Those do exist in C++, and are implemented in just the same way, but should
be avoided.
 
L

Lars Uffmann

Rolf said:
Lars Uffmann wrote:
[.. variadic functions ..]
Those do exist in C++, and are implemented in just the same way, but should
be avoided.

Well - of course - _should be_ - but at some point it might be helpful
to know they are there :) printf is a nice example of when they come in
handy - unless cout can cover the full functionality of that :)
 
E

Erik Wikström

Rolf said:
Lars Uffmann wrote:
[.. variadic functions ..]
Those do exist in C++, and are implemented in just the same way, but should
be avoided.

Well - of course - _should be_ - but at some point it might be helpful
to know they are there :) printf is a nice example of when they come in
handy - unless cout can cover the full functionality of that :)

I am quite sure that there is no formatting that you can achieve with
printf() that you can not make with cout, but it is a lot harder with
cout. However in the next version of the standard we will see something
called variadic templates which should allow for a typesafe
implementation of printf().
 
J

James Kanze

Rolf said:
Lars Uffmann wrote:
[.. variadic functions ..]
Those do exist in C++, and are implemented in just the same
way, but should be avoided.
Well - of course - _should be_ - but at some point it might be helpful
to know they are there :) printf is a nice example of when they come in
handy - unless cout can cover the full functionality of that :)

ostream has considerably more functionality than printf. There
are a lot of things that you can do with ostream that you cannot
do with printf/fprintf/sprintf.
 
J

James Kanze

Lars Uffmann wrote:
[.. variadic functions ..]
Those do exist in C++, and are implemented in just the same
way, but should be avoided.
Well - of course - _should be_ - but at some point it might be helpful
to know they are there :) printf is a nice example of when they come in
handy - unless cout can cover the full functionality of that :)
[/QUOTE]
I am quite sure that there is no formatting that you can
achieve with printf() that you can not make with cout, but it
is a lot harder with cout.

It's generally a lot easier with cout. About the only
printf formatting I know that you can't easily achieve with
ostream is the ' ' modifier, i.e.: "% d".
However in the next version of the standard we will see
something called variadic templates which should allow for a
typesafe implementation of printf().

You *can* simulate printf formatting with ostream today,
although why you would want to? Boost::format supports almost
all of the printf formatters (I think the ' ' flag is one of the
exceptions), and a bit more. I also used to have a class Format
which was 100% compatible with the X/Open printf, including the
X/Open extensions, and attempted, at least, to make it simple to
support user defined classes as well. (I stopped maintaining it
because in the end, I couldn't think of a context where printf
style formatting was preferable over ostream style formatting.)
 
T

Tomás Ó hÉilidhe

James Kanze said:
As far as the compiler is concerned, no. As far as anyone who
reads the code is concerned, the first marks you as a C hacker,
who doesn't understand C++.


Actually I coded for a few years in C++ and always used () instead of
(void). Now I've been programming in C for the last year or so I'm
(obviously) using (void) instead of ().

Now that I'm doing a bit of C++ again, I'm more comfortable with (void).
So contrary to your claim, I'm someone who writes (void) in C++, but who
also understands C++.

(FWIW: even the C experts find the first an abomination.


Of course not. What could be wrong with "int main(void)"?

To be lived with in C, because there's no other alternative.)


I like having (void) instead of () in C, because then when I see empty
parentheses I know straight away that it's the invocation of a function.
 
T

Tim H

It's generally a lot easier with cout. About the only
printf formatting I know that you can't easily achieve with
ostream is the ' ' modifier, i.e.: "% d".

"can't achieve" or "can't easily achieve" ?
You *can* simulate printf formatting with ostream today,
although why you would want to? Boost::format supports almost
all of the printf formatters (I think the ' ' flag is one of the

It also lacks the * formatter, which hurts me.
exceptions), and a bit more. I also used to have a class Format
which was 100% compatible with the X/Open printf, including the
X/Open extensions, and attempted, at least, to make it simple to
support user defined classes as well. (I stopped maintaining it
because in the end, I couldn't think of a context where printf
style formatting was preferable over ostream style formatting.)

common things I do:

printf("%3d: %#08x\n", x, y);

std::cout << boost::format("%3d: %#08x\n") %x %y;

How do you do this easily with plain old cout?

Tim

p.s.

If format supported * I'd have said:

printf("%3d: %#0*x\n", x, y_width/4, y);
 
J

James Kanze

"can't achieve" or "can't easily achieve" ?

Can't achieve directly. You can achieve anything if you format
into an std::eek:stringstream, and then do padding, etc. manually.
It also lacks the * formatter, which hurts me.

What do you mean by "the * formatter"? The only place you can
use a '*' in a format specification of printf is for width and
precision. From what I understand of boost::format (but
admittedly, I've never used it), it allows all of the normal
manipulators as well, so you can use setw() and setprecision()
to achieve the same effect as the '*'. (setprecision() will
affect all of the following variables, where as ".*" won't, so
they effect isn't exactly the same.)

Another thing which I think is lacking, however, is precision of
an int or a string, e.g. printf( "%-10.8s|%5.3d",
"abcdefghijklmnopqrstuvwxyz", 2 ) will output:
"abcdefgh | 002"
From what I've seen, however, most people don't actually know
the embedded language used by printf very well, and aren't aware
of such features to begin with.
common things I do:

printf("%3d: %#08x\n", x, y);
std::cout << boost::format("%3d: %#08x\n") %x %y;
How do you do this easily with plain old cout?

std::cout << std::setw( 3 ) << x
<< Gabi::HexFmt( 8, ios::showbase ) << y << '\n' ;

Except that I'd usually write:

std::cout << std::setw( 3 ) << x
<< "0x" << Gabi::HexFmt( 8, ios::uppercase ) << y <<
'\n' ;

since I prefer the format "0x0000ABCD" for hex.
 
L

LR

James said:
Can't achieve directly. You can achieve anything if you format
into an std::eek:stringstream, and then do padding, etc. manually.

Isn't this, or can't this be, assuming int x;

std::cout << (x >= 0 ? std::string(' ') : std::string());
std::cout << x;

Or have I missed something?
What do you mean by "the * formatter"? The only place you can
use a '*' in a format specification of printf is for width and
precision. From what I understand of boost::format (but
admittedly, I've never used it), it allows all of the normal
manipulators as well, so you can use setw() and setprecision()
to achieve the same effect as the '*'. (setprecision() will
affect all of the following variables, where as ".*" won't, so
they effect isn't exactly the same.)

And even if it is lacking, there's always code like this, no matter how
annoying and bad it might be,

std::string df(const unsigned int width) {
std::eek:stringstream ox;
ox << "%" << width << "d\n";
return ox.str();
}
....
printf(df(5).c_str(),x);
....

Another thing which I think is lacking, however, is precision of
an int or a string, e.g. printf( "%-10.8s|%5.3d",
"abcdefghijklmnopqrstuvwxyz", 2 ) will output:
"abcdefgh | 002"
From what I've seen, however, most people don't actually know
the embedded language used by printf very well, and aren't aware
of such features to begin with.




std::cout << std::setw( 3 ) << x
<< Gabi::HexFmt( 8, ios::showbase ) << y << '\n' ;

Except that I'd usually write:

std::cout << std::setw( 3 ) << x
<< "0x" << Gabi::HexFmt( 8, ios::uppercase ) << y <<
'\n' ;

I'm not familiar with 'Gabi'. Is that part of the standard?

Adding to the snippet above,
const int x = 123;
const int y = 0xabcd;

my compiler produces,
123: 0x00abcd
for the OP's printf statement. I can't tell from reading the only draft
copy of a C standard I have, but I'm going to guess that the '%#08x'
format width calculations include the '0x'. Assuming that in the OPs
snippet x and y were meant to be int and sizeof(int) is 4 and the number
of bits per char is 8, I wonder if the OP meant '%#010x'?

So using plain old cout, what's wrong with,

std::cout
<< std::dec
<< std::setw(3)
<< x
<< ": "
<< (y == 0 ? std::string() : std::string("0x")) << std::setfill('0')
<< std::setw(6) // or std::setw(8) if you wanted 8 hex digits
<< std::hex
<< y
<< std::endl;


since I prefer the format "0x0000ABCD" for hex.

I suppose it would be superfluous to mention std::uppercase.

I'm not sure I understood the OP's question or your response. What am I
missing, please?

LR
 
L

LR

LR said:
Isn't this, or can't this be, assuming int x;

std::cout << (x >= 0 ? std::string(' ') : std::string());
std::cout << x;

Or have I missed something?


And even if it is lacking, there's always code like this, no matter how
annoying and bad it might be,

std::string df(const unsigned int width) {
std::eek:stringstream ox;
ox << "%" << width << "d\n";
return ox.str();
}
...
printf(df(5).c_str(),x);
...



I'm not familiar with 'Gabi'. Is that part of the standard?

Adding to the snippet above,
const int x = 123;
const int y = 0xabcd;

my compiler produces,
123: 0x00abcd
for the OP's printf statement.

Sorry. I wrote OP, but I meant Tim H. And below as well.
 
T

Tim H

Multiple responses in one!

That's right. For some reason I find myself using that fairly often.
And even if it is lacking, there's always code like this, no matter how
annoying and bad it might be,

std::string df(const unsigned int width) {
std::eek:stringstream ox;
ox << "%" << width << "d\n";
return ox.str();}
...
printf(df(5).c_str(),x);
...

Sure, there are always workaround, but my point is that printf-style
output is often the simplest and most direct way to get formatted
output. This is furthering my argument :)

I do wish that boost::format supported the * conversion.

WTH is Gabi? This also bolsters my point. In order to get simpler
output, you (a C++ expert, it seems) go outside the standard
implementation. And really - is what you wrote simpler or more
comprehensible than what I wrote?

On the other hand, you support your own argument that people don't
fully know printf. %# implies the 0x, and the 8 includes the prefix.
my compiler produces,
123: 0x00abcd
correct

So using plain old cout, what's wrong with,

std::cout
<< std::dec
<< std::setw(3)
<< x
<< ": "
<< (y == 0 ? std::string() : std::string("0x")) << std::setfill('0')
<< std::setw(6) // or std::setw(8) if you wanted 8 hex digits
<< std::hex
<< y
<< std::endl;

Yikes! 1 line of code becomes 10.

That is my point. boost::format and printf-style output are not as
useless as many C++ folks would have me believe. They are simpler and
more direct than equivalent iostream manipulations for all but the
most trivial output.

Tim
 
L

LR

Tim said:
Multiple responses in one!


That's right. For some reason I find myself using that fairly often.


Sure, there are always workaround, but my point is that printf-style
output is often the simplest and most direct way to get formatted
output. This is furthering my argument :)

Or conversely, since my opinion differs it counters your argument. ;)
I do wish that boost::format supported the * conversion.


WTH is Gabi? This also bolsters my point. In order to get simpler
output, you (a C++ expert, it seems) go outside the standard
implementation. And really - is what you wrote simpler or more
comprehensible than what I wrote?

I'm wondering if this Gabi:: is more typesafe than boost format?


On the other hand, you support your own argument that people don't
fully know printf. %# implies the 0x, and the 8 includes the prefix.


correct

I didn't know that. OTOH, I rarely use printf.

Yikes! 1 line of code becomes 10.

Well, if you wanted to, you could write that all on one line. ;)


That is my point. boost::format and printf-style output are not as
useless as many C++ folks would have me believe.
> They are simpler

I'm less certain about them being simpler. It's not that I think C++
streams etc are easy as pie to use, they have some complications, but I
wonder how many people who use printf regularly would know the ins and
out of %#08x off the top of their heads.

Maybe not exactly on point, but I remember a long ago discussion about
printf on usenet and finding out that some of the posters seemed unaware
that the format didn't have to be available at compile time. That
doesn't seem simpler to me.




and
more direct than equivalent iostream manipulations for all but the
most trivial output.

I'm not sure that I agree with that either. At this point, at least for
me, although I can't say that I'm an expert in either, the C++ stream
stuff all looks clearer to me. I had to read up on %#08x very carefully
and try it to figure out the results.

And did I mention typesafety, again and again?

And the advantage of having stringstreams, fstreams and standard input,
output and error all use the same interface?

And the ability to overload operator<< and use it to output a class
fairly easily? I don't think that can easily be done with printf.

For example what about this untested snippet.

struct SomeType {
int a,b,c;
...
};

std::eek:stream &operator<<(std::eek:stream &o, const SomeType &s) {
o << "SomeType(" << s.a << "," << s.b << "," << s.c << ")";
return o;
}

Can be used like,
SomeType x,y;
std::cout << x << " " << y << std::endl;

Whats this going to look like with printf?

LR
 
T

Tim H

I'm wondering if this Gabi:: is more typesafe than boost format?

boost::format is totally type safe. I even used it on a bignum type
and it
"just worked". Any streamable type can be fed to format.
Well, if you wanted to, you could write that all on one line. ;)

OK< then count the characters. :)
I'm less certain about them being simpler. It's not that I think C++
streams etc are easy as pie to use, they have some complications, but I
wonder how many people who use printf regularly would know the ins and
out of %#08x off the top of their heads.

OK, I guess it's my C background, but any C programmer who can't tell
me
what %#08x does (even if they get the 8 vs 6 character thing wrong) is
not
getting a job at my company.
And did I mention typesafety, again and again?

Yuu did. :) read teh boost.format documentation.
And the advantage of having stringstreams, fstreams and standard input,
output and error all use the same interface?

boost::format produces an object which is itself streamable.
And the ability to overload operator<< and use it to output a class
fairly easily? I don't think that can easily be done with printf.

Nope. I would not advocate printf in C++ - boost::format is 99% as
powerful
and 1000% safer.

Tim
 
J

James Kanze

Isn't this, or can't this be, assuming int x;
std::cout << (x >= 0 ? std::string(' ') : std::string());
std::cout << x;
Or have I missed something?

Or even:

std::cout << std::string( x >= 0, ' ' ) << x ;

Good catch. (Of course, it's not quite the same thing, if e.g.
instead of x, you're calling some expensive function.)

[...]
I'm not familiar with 'Gabi'. Is that part of the standard?

No. But the standard doesn't forbid you from writing your own
classes. The standard manipulators (with the exception,
perhaps, of setw) are really designed more to be examples, than
to be used directly. In normal coding, you don't want to say:
use such and such physical format. You want to say, use the
format appropriate for something with the X semantics, and then
define that format in one, centralized location.
Adding to the snippet above,
const int x = 123;
const int y = 0xabcd;
my compiler produces,
123: 0x00abcd
for the OP's printf statement.

I know. You can't directlyl produce the format I want with
either printf or ostream.

What you can do with ostream is define a new type that outputs
with whatever format you want, and use that. Something like:

class HexInt
{
public:
explicit HexInt( unsigned i ) : myI( i ) {}
friend std::eek:stream&
operator<<( std::eek:stream& dest,
HexInt obj )
{
Gabi::IOSave s( dest ) ;
dest.fill( '0' ) ;
dest.setf( std::ios::hex, std::ios::basefield ) ;
dest.setf( std::ios::uppercase ) ;
dest << "0x" << std::setw( 8 ) << obj.myI ;
return dest ;
}

private:
unsigned myI ;
} ;

One might argue that it's wordier than necessary, but it's still
pretty easy. And it definitely keeps all of the code in one
place---the day where your boss says that all hex output must
use lower case, you don't have to change upteen-dozen printf
formats; you just change this one class.

This is an important feature of ostream. Once you've used it,
you realize that anything not supporting it is simply
unacceptable. (As I said, I've not used boost::format to be
sure. But I think you could use something like this with it,
e.g.:

std::cout << boost::format( "%2$s %1$x" )
% HexInt( myInt ) % myString << std::endl ;

. I seem to recall reading that there is even a simpler format,
for such cases: no %n$f, but just something like {1} {2}.)
I can't tell from reading the only draft copy of a C standard
I have, but I'm going to guess that the '%#08x' format width
calculations include the '0x'. Assuming that in the OPs
snippet x and y were meant to be int and sizeof(int) is 4 and
the number of bits per char is 8, I wonder if the OP meant
'%#010x'?

He meant '%#08x'. That's what I meant by having to deal with a
baroque language within a language: that parses:

% start a format specifier
# use alternative format (for integral types, show
base, for other types, something else entirely)
0 use 0 as a fill character
8 output a minimum of 8 characters
x use hexadecimal, with lower case letters.
So using plain old cout, what's wrong with,
std::cout
<< std::dec
<< std::setw(3)
<< x
<< ": "
<< (y == 0 ? std::string() : std::string("0x")) << std::setfill('0')
<< std::setw(6) // or std::setw(8) if you wanted 8 hex digits
<< std::hex
<< y
<< std::endl;

Several things:
-- the next code probably isn't expecting to output in hex:
you've got to reset the format to whatever it was
previously,
-- it's a lot worder than it should be, and
-- you're specifying the physical formatting (rather than the
logical formatting) in the output statement.
Using your own manipulator (which, correctly designed, restores
the formatting state at the end of the full expression), you
solve all three of these problems.

With printf, the first is automatically solved. The second is
solved, but at the cost of using a baroque language within a
language which no one really knows. And it's very, very
difficult to solve the third---you'd need to write something
like:
printf( (std::string( "some text " )
+ hexFmt
+ " whatever).c_str(), variable ) ;
And of course, you have all of the disadvantages of printf: if
hexFmt actually specifies an unsigned long, and your variable is
of type int, you're in trouble, and you can't very well extend
it for your own types (e.g. BigDecimal).
I suppose it would be superfluous to mention std::uppercase.

Which would result in "0X0000ABCD".
I'm not sure I understood the OP's question or your response.
What am I missing, please?

Probably a deep knowledge of the printf nested language. (I
know it because I've actually implemented printf on one
occasion.)

More importantly, like most people, you probably don't
understand the importance of using custom manipulators. The
iostream is a framework which allows you to create much more
powerful things. I don't think I've ever written an application
without a few custom streambuf's (especially filtering
streambufs), and which didn't use custom manipulators and custom
formatting/parsing types almost exclusively.
 
J

James Kanze

On Jan 6, 7:37 am, LR <[email protected]> wrote:

[...]
Sure, there are always workaround, but my point is that
printf-style output is often the simplest and most direct way
to get formatted output.

My experience is that printf-style output is usually overly
complicated. It provides very limited predefined formatting for
a very limited set of types---typically, I'm dealing with a type
printf can't handle, or I need a format it hasn't predefined.
And even when printf can handle the job, the language it uses is
very baroque, not very well known, and not very clear.
This is furthering my argument :)

If you'll look at his posting in its entirity, you'll see that
he misinterpreted your format specifiers. I know the language
in a language used by printf pretty well, having actually
implemented printf in an implementation of the C standard
library (with the X/Open extensions). But I've not found this
to be the case with any of my collegues---as soon as I do
anything but the simplest formatting, they just stare at the
format specifier.
I do wish that boost::format supported the * conversion.

It wouldn't be that hard to add. (My old GB_Format supported
it.) But since better solutions exist (e.g. manipulators),
why bother.
WTH is Gabi?

It's my application specific manipulator, which outputs hex in
the way the project specifies. If the project changes the
rules, I modify it, instead of searching God knows how much
source code looking for string constants that may or may not
have to be modified.

It's called abstraction.
This also bolsters my point. In order to get simpler
output, you (a C++ expert, it seems) go outside the standard
implementation.

I use the standard classes the way they were meant to be used.
To build up whatever my application needs.

Something you cannot do with printf, which pretty much means
that you don't want to use printf unless you really have to.
And really - is what you wrote simpler or more comprehensible
than what I wrote?

From experience, it's an order of magnitude more readable. At
least, that's what my collegues (over some 15 years) tell me.
How many people know off hand what the '#' flag means in a
format specifier?

Don't forget that I worked in C some ten years before starting
C++, so I have extensive experience with both. And that I was
very used to the C way of doing things when I started using C++,
to the point of writing my own Format class which supported all
of the printf specifiers, including the X/Open extensions to
them. I know both systems inside out.
On the other hand, you support your own argument that people
don't fully know printf. %# implies the 0x, and the 8
includes the prefix.

And the '0' means use 0 as a fill character, rather than ' '.

I know that. I've implemented it. I also implemented a 100%
compatible emulation based on ostream. (More compatible than
boost::format. But not as flexible, because mine didn't allow
manipulators. And in the end, you *don't* want to specify the
format in the output string---you want to specify it
separately.)
Yikes! 1 line of code becomes 10.
That is my point. boost::format and printf-style output are
not as useless as many C++ folks would have me believe.

They are in real code, in real applications, no engineer would
use either of these examples---neither are readable by the
average programmer. In a real application, you'll define a
standard way to output values in hex, and implement a
manipulator or a decorator class which does it. Application
programmers will use your manipulator or your decorator: in sum,
they'll just say "I want output in the application specific hex
format, whatever that happens to be today".

In the end, I guess, it's just a question of good engineering.
If you never have to modify the code, then anything is fine, and
if you know the printf formatting language, it will usually
involve less typing. As soon as you have to maintain the code,
however, printf becomes a nightmare, where as ostream provides
the hooks you need to create readable code, in which you can
modify a format application wide without having to search every
line of code in the application.

Consider the printf equivalent to my code using Gabi::HexFmt:
printf( (idFormat + ": " + hexFormat + '\n').c_str(), x, y ) ;
Is that really simpler than:
std::cout << idFmt << x << ": " << hexFmt << y << std::endl ;
Especially considering that the types of x and y might vary.
They are simpler and more direct than equivalent iostream
manipulations for all but the most trivial output.

It's useless for all but the most trivial output, because it
only provides trivial formatting, it only provides formatting
for the most trivial types, and it doesn't allow extenting nor
(at least not easily) does it allow centrally defining the
formatting information.
 
J

James Kanze

Tim H wrote:

[...]
I'm wondering if this Gabi:: is more typesafe than boost format?

Gabi is a namespace, and HexFmt is a manipulator, which works
more or less like std::setw(). HexFmt is also a poor example,
because it's really designed more to be an example of how to
write these sort of things. In an actual application, you's use
something similar, but which wouldn't require the ios::uppercase
argument---whether you output hex in upper or lower case would
be determined centrally, and not at each output site. (An
application specific manipulator could also output the "0x",
although it's not really very idiomatic for manipulators to
generate output.)

More recently, I've tended to use the decorator idiom more than
manipulators, since it's a lot more flexible---you could, for
example, output negative numbers as "(123)", instead of "-123".
(At my site, there's a ParsableString decorator, which can input
or output std::string, quoting it if the string contains
meta-characters, and stripping such quotes on input.)
I'm not sure that I agree with that either.

printf uses a language in a language. The language is very,
very terse (it was invented by people who programmed on real
tty's), and thus, not particularly readable. It contains a lot
of little known features.
At this point, at least for me, although I can't say that I'm
an expert in either, the C++ stream stuff all looks clearer to
me. I had to read up on %#08x very carefully and try it to
figure out the results.
And did I mention typesafety, again and again?

Or expandability.
And the advantage of having stringstreams, fstreams and
standard input, output and error all use the same interface?

printf, fprintf and sprintf all use the same language in a
language as well. The real advantage is when you start writing
your own streambuf's.

The fundamental difference between the two is the iostream is
framework, well adopted for customizing to the specific needs of
your application. printf et al. provides a small number of
fixed formats for a small number of types, and you can't go
beyond that. If you never have to output a user defined type,
never have to output to anything but a classical file, and it
doesn't matter if you constantly output the same semantic
information in different formats, depending on where it is
output, printf works fine. (As long as you never change any of
the data types in the program either, of course.)
 
T

Tim H

Gabi is a namespace, and HexFmt is a manipulator, which works
more or less like std::setw(). HexFmt is also a poor example,
because it's really designed more to be an example of how to
write these sort of things. In an actual application, you's use
something similar, but which wouldn't require the ios::uppercase
argument---whether you output hex in upper or lower case would
be determined centrally, and not at each output site. (An
application specific manipulator could also output the "0x",
although it's not really very idiomatic for manipulators to
generate output.)

That's a fine answer. But not the end-all. I can think of many times
where the format is very context-specific. Where sometimes hex is 2
hexits, 4 hexits, 8 hexits, etc. But Your answer could work here too.

Where do you reset the stream's settings? Or do they get left in
"whatever was last" state?
printf uses a language in a language. The language is very,
very terse (it was invented by people who programmed on real
tty's), and thus, not particularly readable. It contains a lot
of little known features.

but it really doesn't take long to master 90% of the useful features
of
it. Don't make it sound harder than it is.
printf, fprintf and sprintf all use the same language in a
language as well. The real advantage is when you start writing
your own streambuf's.

Again, I'd never advocate printf() proper, when typesafe alternatives
are
available. And boost::format DOES work with user defined types.
Also,
you're mentioned specifically in the boost::format docs, which I did
not
realize until yesterday :)

I guess we'll just agree to do things differently. I am very
comfortable
with printf() style formatters, and can read them almost as quickly as
plain code. I know how to use them when I need them, and they express
the
vas majority of what I need to output. I find boost::format to be a
very
useful tool when I need to do formatted IO very simply.

When I have a custom type, I almost always add a operator<<(ostream),
and
when appropriate I make it check the flags on the stream for it's
formatting. Thus, it works with boost::format or ostream directly.

Lastly, I admit to being a C programmer still learning C++. Iostreams
do
feel weird to me (I really liked Java's to_string() model, iostreams
is
similar but inside out).

Cheers.

Tim
 

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

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,065
Latest member
OrderGreenAcreCBD

Latest Threads

Top