From: bab@se39.wg2.waii.com (Brian Button)
Newsgroups: comp.lang.c++
Subject: Re: streams
Date: 14 Oct 92 19:43:42 GMT
	<1992Oct13.225552.12965@informix.com>
Organization: Western Geophysical Exploration Products
In-reply-to: cshaver@informix.com's message of 13 Oct 92 22:55:52 GMT

In article <1992Oct13.225552.12965@informix.com> cshaver@informix.com (Craig Shaver) writes:
   In article <1992Oct13.155518.22845@rs6000.bham.ac.uk> pickerig@dns0.bham.ac.uk (Mr. G. Pickering) writes:
   >My first reaction is to use FILE functions rather than streams, unless
   >you have a good reason to use streams. This is just the way I do things,
   >feel free to flame me for this.

   Praise the lord for a breath of fresh air -- streams are hard to use!

Really? I spent about a week, and I feel that I understand them very
well. In fact, I've written my own streambuf and stream classes. These
let me treat a UDP socket as I would treat any other input source.

   >
   >In this case you wouldn't have the problem, you would just pass the
   >file pointer to whichever service functions that need access to the
   >file.
   >
   >You can still do:
   >
   >  FILE* input_file;
   >  if (input_flag)
   >  {
   >    input_file = stdin;
   >  }
   >  else
   >  {
   >    input_file = fopen("in_file","r");
   >  }
   >
   >  if (input != NULL)
   >  {
   >    // do some stuff
   >  }
   >
   >Ok, so it's not C++, but I subscribe to the school of
   >thought that "if it works reliably...use it".  

I spent a few minutes and came up with an equivalent iostream
implementation of this. This simple program will echo each line read
from cin or from a named file until EOF is reached. IMHO, it is no
more complicated than using stdio.

------------------------------
#include    <iostream.h>
#include    <strstream.h>
#include    <fstream.h>

int main( int argc, char ** argv )
{
                                            // Declare generic pointer to I/O
                                            // object 
    istream * is;

                                            // If file is passed in to us,
                                            // create a file object. Need to
                                            // use new because any object
                                            // created locally inside the
                                            // braces would be closed
                                            // immediately as that object
                                            // passed out of scope
    if( argc == 2 )
    {
        is = new ifstream( argv[ 1 ] );
    }
    else
    {
        is = &cin;
    }
    
                                            // Read from file forever or until
                                            // we reach the end of it
    while( *is )
    {
                                            // Declare somewhere to stuff
                                            // arbitrarily sized data
        ostrstream out_str;

                                            // Read an entire line into
                                            // out_str\'s streambuf. Remember
                                            // to junk the newline, which was
                                            // not pulled off the stream
        is->get( *out_str.rdbuf( ));
        is->ignore( 1, '\n' );
        
        cout << "Read <" << out_str.rdbuf( ) << ">" << endl;
    }
    
                                            // Delete the object created. 
    if( argc == 2 )
    {
        delete is;
    }
    
    return 0;
}
------------------------

The only added complexity here is the new'ing and subsequent
delete'ing of the ifstream object. However, this is no more a burden
on the programmer than remembering to close a file before exiting his
program. You don't really HAVE to do it, since the cleanup code will
do it for you, but it's a good idea.

The main advantage that using streams would have here is inside the
while loop. I can read arbitrarily large lines into the ostrstream
object and never have to worry about pre-allocating memory or deleting
it after I'm finished with it.

   And I can use simple printf and scanf too?  Huh, Huh?

If you really want to. You do forsake type checking and extensibility.
The stream formatting functions are pretty versatile, too, although
I'm not sure if they're more flexible than stdio's.

Anyhow, this isn't intended to be a flame, just my opinion.

bab

--
|-----------------------|----------------------------------------------------|
| Brian Button          | email : button@wg2.waii.com                        |
| Design Engineer       |         bab@buster.stafford.tx.us                  |
| Western Geophysical   | voice : (713)964-6221                              |
| 3600 Briarpark        |                                                    |
| Houston, Texas  77042 |                                                    |
|----------------------------------------------------------------------------|
Newsgroups: comp.lang.c++