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
open() returns a file descriptor that can be used by fstream.
Ian
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.
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.