Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

converting FILE * to stream?

5 views
Skip to first unread message

Jean-Marc Valin

unread,
Jan 25, 2000, 3:00:00 AM1/25/00
to
Hi,

I need to convert the (FILE *) I get from the popen() call to a C++ stream. Is
there a way to do that? or is there a call similar to popen that returns a C++
stream?

Jean-Marc

--
Jean-Marc Valin
Universite de Sherbrooke - Genie Electrique
val...@gel.usherb.ca

Ian Collins

unread,
Jan 26, 2000, 3:00:00 AM1/26/00
to
Jean-Marc Valin wrote:

open() returns a file descriptor that can be used by fstream.

Ian

Dietmar Kuehl

unread,
Jan 26, 2000, 3:00:00 AM1/26/00
to jean-ma...@hermes.usherb.ca
Hi,
In article <388E5ACC...@hermes.usherb.ca>,

Jean-Marc Valin <jean-ma...@hermes.usherb.ca> wrote:
> I need to convert the (FILE *) I get from the popen() call to a C++
> stream. Is there a way to do that?

Yes, there is a way but it is not readily available. The standard does
not provide a direct conversion between 'FILE*' or file descriptors (as
was suggested in another reply) and streams. However, in C++ you can
fairly easy create new streams by deriving from the class
'std::streambuf'. This can be used to access 'FILE*' or files using
file descriptors with the OS functions from streams. Here is a simple
(and untested) version of a stream buffer using 'FILE*':

#include <cstdio>
#include <streambuf>
class stdiobuf: public std::streambuf {
public:
typedef std::streambuf::int_type int_type;
typedef std::streambuf::traits_type traits_type;

stdiobuf(std::FILE* file): m_file(file) {}

protected:
int_type underflow() {
int_type rc = std::fgetc(file);
std::ungetc(c, file);
return std::fpeekc(file);
}
int_type uflow() { return std::fgetc(file); }
int_type overflow(int_type c) {
return std::fputc(c, file) == EOF? traits_type::eof(): c;
}
};

This is a first version which should be suitable for both reading and
writing. For example, you can do something like this:

int main() {
std::FILE* fp = std::fopen("/tmp/foo", "w");
stdiobuf sbuf(fp);
std::ostream out(&sbuf);
out << "foo!\n";
std::fclose(fp);
}

This should write to the file "/tmp/foo". For more convenience you
might want to derive a class from 'std::ostream' which does the
construction of the 'stdiobuf' and initialization of the base class
automatically. For better performance you might also want to add
buffering to the stream buffer.

> or is there a call similar to popen that returns a C++ stream?

This can be implemented similar to the 'stdiobuf' above: Just use
'pipe()' to create the file descriptors and use the OS function on the
file descriptors in the functions 'overflow()', 'underflow()', and
'uflow()'.

I'm still planning to submit a bunch of stream buffers to the Boost
library (see <http://www.boost.org/>) but I haven't come around to
doing so, partially because nobody pushes me to do the work...
--
<mailto:dietma...@claas-solutions.de>
homepage: <http://www.informatik.uni-konstanz.de/~kuehl>


Sent via Deja.com http://www.deja.com/
Before you buy.

Ron Natalie

unread,
Jan 26, 2000, 3:00:00 AM1/26/00
to Ian Collins

Ian Collins wrote:

> > I need to convert the (FILE *) I get from the popen() call to a C++ stream. Is

> > there a way to do that? or is there a call similar to popen that returns a C++
> > stream?
>

> open() returns a file descriptor that can be used by fstream.

popen is an entirely different function and returns a FILE. Of course on
most UNIX implementations there exists a macro to extract the file descriptor
from a FILE struct.

I know of no portable way.

0 new messages