[comp.lang.c++] How do I convert from ostream to FILE?

holub@violet.berkeley.edu (Allen Holub) (05/16/91)

Is there an official way to convert from an ostream either to a FILE pointer
or file descriptor? I need to use a few C routines that take file-descriptor
arguments in a stream-based C++ application compiled under Borland C++ 2.0.

steve@taumet.com (Stephen Clamage) (05/17/91)

holub@violet.berkeley.edu (Allen Holub) writes:

>Is there an official way to convert from an ostream either to a FILE pointer
>or file descriptor? I need to use a few C routines that take file-descriptor
>arguments in a stream-based C++ application compiled under Borland C++ 2.0.

You don't say whether you are using AT&T version 1.2-style (old) streams
or version 2.x-style (new) iostreams.

Old-style streams were built on C Standard I/O, and you can just pick up
the FILE pointer.

New-style iostreams do not use C Standard I/O at all (except for
stdiostream, which is recommended against).  So there is no FILE
pointer available.

Beyond that, an ostream is not necessarily file-based.  It uses a
streambuf-derived class for its output, and this streambuf-derived
class might be a filebuf (using a file), a strstreambuf (using a
char array), or some user-defined class.  So there is no guarantee
that an ostream will have a file associated with it.

In the event that an ostream-derived class uses a filebuf (as do
cout and cerr), you can use the public member function ios::rdbuf()
to get the associated streambuf, then invoke public member function
fd() to get the file descriptor.  Of course, fd() is not a member
of streambuf, but of filebuf, so you need a cast, which is not
safe unless you know you are dealing with a filebuf-derived
buffer class.  Example:

    #include <fstream.h>
    main()
    {
	cout << "fd for cout is "
	     << ((filebuf*)cout.rdbuf())->fd() // UNSAFE CAST
	     << endl;
	return 0;
    }

This makes sense on systems which have the Unix-like concept of small
integers representing a file as known to the operating system.  (DOS is
such a system.)
-- 

Steve Clamage, TauMetric Corp, steve@taumet.com

sking@nowhere.uucp (Steven King) (05/17/91)

In article <732@taumet.com> steve@taumet.com (Stephen Clamage) writes:
>holub@violet.berkeley.edu (Allen Holub) writes:
>
>>Is there an official way to convert from an ostream either to a FILE pointer
>>or file descriptor? I need to use a few C routines that take file-descriptor
>>arguments in a stream-based C++ application compiled under Borland C++ 2.0.
>
>In the event that an ostream-derived class uses a filebuf (as do
>cout and cerr), you can use the public member function ios::rdbuf()
>to get the associated streambuf, then invoke public member function
>fd() to get the file descriptor.  Of course, fd() is not a member
>of streambuf, but of filebuf, so you need a cast, which is not
>safe unless you know you are dealing with a filebuf-derived
>buffer class.  Example:
>
>    #include <fstream.h>
>    main()
>    {
>	cout << "fd for cout is "
>	     << ((filebuf*)cout.rdbuf())->fd() // UNSAFE CAST
>	     << endl;
>	return 0;
>    }
>

   A few minor quibbles...

   The library distributed with cfront 2.0 has cin & cout instances
 of istream_withassign and ostream_withassign, repectively, and neither
 is defined as derived from filebuf or have a filebuf as member. ( I
 presume that the actual initialization of cin, etc. uses a filebuf ) 

   Objects derived from fstreambase ( ie. ofstream and ifstream ) have
 the member function rdbuf() which returns a pointer to a filebuf,
 rendering the cast unnecessary, ie:

    ifstream ins ;
    int fd = ins.rdbuf() -> fd() ;


-- 
If it don't stick, stink, or sting
It ain't from Texas.
                                        ..!cs.utexas.edu!ut-emx!nowhere!sking