[LC++]IO in C++
Carlo Wood
carlo at alinoe.com
Fri Nov 2 01:07:48 UTC 2001
On Thu, Nov 01, 2001 at 02:42:47PM +1030, Mark Phillips wrote:
> Hi,
>
> Suppose I have an integer and I wish to convert it to a
> string. I can do:
>
> int myInt=259;
> char myCstr[20];
> sprintf(myCstr, "%d", myInt);
Or
int myInt=259;
ostringstream oss;
oss << myInt;
(use oss.str())
> Or suppose I have a string and I wish to convert it to an
> int. I can do:
>
> int myInt;
> string myString="259";
> istringstream iss(myString);
> iss>>myInt;
>
> But both of these seem a bit inelegant. Are there better
> ways of doing this kind of thing.
What is inelegant about it?
> The other thing is, I have heard it said that cout is bad for
> doing output formatting, and that printf should be used, even
> in C++. Do people agree?
Absolutely not. You should use solely cout/cerr and never
printf. People who say you should use printf are only looking
at the syntax/layout and like printf better because it looks
better (which is only because they are used to it).
If you write a *simple* program that only does very simple
output, then there is no big disadvantage in using printf.
However - when you write a Object Oriented program then you
will need to output objects rather than only builtin-types.
Then you will appreciate the advantage of using ostreams.
Another advantage of using ostreams appart from that they are
type-safe and extendable is they result in faster code: by
using the overload mechanism of C++, you use compile time
to decide which function to call instead of doing that at
runtime. A printf("The ammount is: %d\n", a); needs to
_decode_ the format string at runtime and then call a function
that can convert an integer to a string. While the code
std::cout << "The ammount is: " << a << '\n';
calls the three different needed functions _directly_.
> What alternatives are there for dealing with IO in C++? There
> seems to be no sensible and flexible framework. Am I wrong?
I think you are wrong. The most powerful reason to use
ostreams is that you treat them just like that: abstract
output streams. You can pass them around.
Consider this code:
template<class T>
class Foo {
T M_t;
public:
Foo(T const& t) : M_t(t) {
Dout(dc::notice,
"You are calling "
<< type_info_of<Foo<T> >().demangled_name()
<< '(' << t << ");");
}
};
where I use the debug output macro "Dout" of libcwd
(http://libcw.sourceforge.net/debugging/)
libcwd allows you to set an ostream somewhere
(with Debug(libcw_do.set_ostream(&std::cout)); )
So the above code could be writing to cout, or cerr, or
a file (or both), or to syslog - or to a pipe that is
send buffered over a socket to a remote site - or to
another program that is filtering it before logging
it and displaying it partly in a window on another
monitor. Moreover, this same code could be writing
directly to the ostream or to a temporal stringstream
because it needed buffering (depending on the history
of previous debug output (`continued' debug output)).
--
Carlo Wood <carlo at alinoe.com>
More information about the tuxCPProgramming
mailing list