Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

using streams.

Status
Not open for further replies.

jyrixx

Programmer
Nov 28, 2001
17
US
ok, let's say i have a function call it foo.
foo wants to be able to look like this:

void foo (<output stream> s, int o)
{
s << &quot;blah blah blah\n&quot;;
}

however, i would like to be able to use cout as one of those streams, so that with this function i could print to a file, cerr, or cout. unfortunatly i have not been able to figure this out.
also, say, o was a flag, in case i couldn't use cout, is there a way to pass an output stream that is null?
so that i wouldn't have to pass an output stream?

first off. what exactly is cout?
is it declared ostream?
if so, can i declare a filestream like this:
ostream out;
or is there another way to do that?

i'm guessing if it was an &quot;ostream&quot; or some other type there would be a template. such as ostream<in> or some sort of flag. which would mean that an ifstream would just be a typedef of something declared as ostream<filein> blah blah blah.
if anyone understands what i'm saying and has some insight, it'd be extremely appreciated since no one else seems to know.

thanks in advance.
 
Lots of questions there...

First off, foo would look like:

void foo( ostream &out, int o )
{
// blah
}


and you could call it like:

foo( cout, 0 );
foo( cerr, 0 );
foo( fout, 0 ); // assuming you've declared fout


because cout, cerr, and any output streams you define (such as fout in the example) will be ostreams or types derived from ostream.

As far as I know, there's no &quot;null stream.&quot;

Here's what cout is exactly:
cout is of the type ostream. ostream a typedef for basic_ostream< char, char_traits< char > >, which is derived from basic_ios< char, char_traits< char > >, which is derived from ios_base.

So yes, it is declared ostream.

No, you can't declare a file stream that way, but you can do it this way:

#include <fstream>
ofstream out( &quot;filename&quot; );


Your guess at how ostream works isn't quite right, but it's sorta along the same path. If you followed what I said above about what exactly cout is, then cin is of the type istream (or basic_istream< char, char_traits< char > >), which is also derived from basic_ios< char, char_traits< char > >.

Chances are, that and the above made little or no sense, so here's an inheritance diagram:

Code:
              ios_base
                 |
                ios
               /    \   
              /               ostream     istream
              \       /
              iostream

where ios, ostream, etc. are just typedefs for basic_ios< char, char_traits< char > >, basic_ostream< char, char_traits< char > >, etc. (as opposed to the equivalents for wchar_t or some other character type).
 
hi,

you can implements a class that handling an ostream object, and than, you, simple, add to that class an overloading of the operator << (ostream &os, &quot;your object&quot;).
 
It sounds like your trying to print a class? then you'll want to do something like this:

class A{
public:
A(){}
void write(ostream &sout)
{
sout << x << &quot; &quot; << y << &quot; &quot; << z <<end;
}
protected:
int x, y, z;
}

and then overload the << operator like this:
ostream & operator<<(ostream &sout,const A &object)
{
A.write(sout);
return sout;
}

That way you can can do this:
int main()
{
int Num = 5;
string S = &quot;Hello there.&quot;;
A yourobject;
cout << Num << &quot; &quot; << S << &quot; &quot; << yourobject <<endl;
return 0;
}

Returning the ostream allows you to chain, and over loading the operator lets you use the familiar syantax. The operator shouldn't be a member of the class, because it doesn't change the value of the object, and the syntax to call it would be odd. You'd call it like this, if it were a member function:
yourobject << cout;
Which means that it couldn't be printed in the middle of a chain of cout statements.

The most common types streams are:
I/O streams - keyboard and monitor (stdio/iostream)
File stream - read and write to hard drive (fstdio/fstream)
Error stream - cerr and the like (stdio/iostream)
String stream - Fun stuff, but not always the best way to do things. (stdio)

The flags are something a little different... they are varibles used to tell the stream information. Most of them are set using functions and flags in the iostream class:
nopos, noskipws, eof(I think it has a flag), eatwhitespace, skipws... there are a ton of them, esspecially for the filestream, but flags are just modifiers and not objects in themselves.

As for null streams... You could feisably pass a stream that goes nowhere, like to a tty that you don't have control or permission too... but runtime errors would likely occur. Likewise trying to read past eof() or read a currupt file would result in unexpected output at best and seg fault or disk curruption at worst. It is always a good idea to check for eof() and !bad() or good() before writing to a stream which you are unsure of it's state (like a new fstream or a reassigned varrible).

Sorry, I got to babbling, but hey I've not been here in a while.
 
More simple:

class A
{
ofstream fileStream;

public:

// a function to intercept cout
void SetStream(streambuf *pStreamBuf)
{ fileStream.ios::rdbuf(pStreamBuf); }


friend ostream& operator << (A &obj, const ostream &os)
{ return obj.fileStream << os; }

friend ostream& operator << (const A &obj, string str)
{ return os << str; }

friend ostream& operator << (ostream &os, const A &obj)
{ return os << obj.fileStream; }
}

in the main:
A obj;

obj << &quot;pippo&quot;;
obj.SetStream(cout.ios::rdbuf()); // to intercept cout
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top