How to get FILE* from std::ostream

S

Soumen

Hi,

Is there a way to get C FILE pointer from std::eek:stream? If so, how?
Looks to me there shouldn't be any since otherwise someone can get
FILE pointer and close it and then that std::eek:stream object becomes
unusable.

I've a std::eek:stream object at my end. And some library I need to use
in the middle of my program expects a log file as FILE pointer. If
there's a way to get FILE pointer from std::eek:stram, my task becomes
little easy. Otherwise, I need to use different file for that library
to log its messages and then sync all those messages in my
std::eek:stream object.

Regards,
~ Soumen
 
S

ShaunJ

Hi Soumen,

You can't do this in a standard way, but if you can get the file
descriptor from the stream -- also a non-standard operation -- you can
create a FILE using the function fdopen.

Cheers,
Shaun
 
J

James Kanze

Is there a way to get C FILE pointer from std::eek:stream?

No. For starters, std::eek:stream doesn't necessarily refer to a
file (or whatever the system considers a file); FILE does. And
even in the case of std::eek:fstream, the two are basically
unrelated, and typically have separate buffers, etc. (The
standard doesn't require this, and an implementation can
implement filebuf in terms of FILE, but it's not the usual
approach.)
If so, how? Looks to me there shouldn't be any since
otherwise someone can get FILE pointer and close it and then
that std::eek:stream object becomes unusable.

You can do that anyway:
dynamic_cast said:
I've a std::eek:stream object at my end. And some library I need
to use in the middle of my program expects a log file as FILE
pointer. If there's a way to get FILE pointer from
std::eek:stram, my task becomes little easy. Otherwise, I need to
use different file for that library to log its messages and
then sync all those messages in my std::eek:stream object.

The obvious solution is to implement a streambuf which uses
FILE, and which supports getting the FILE*.
 
J

James Kanze

You can't do this in a standard way, but if you can get the
file descriptor from the stream -- also a non-standard
operation -- you can create a FILE using the function fdopen.

There is no fdopen function in standard C/C++; it's a Posix
extension. And even where your suggestion would work, you'd
still have separate buffers for the two, which could result in
messages becoming scrambled.
 
S

Soumen

Hi Shaun,

Could you elaborate little more or provide some code snippet to do
that?

Say my existing code is:

std::filebuf fb;
fb.open("tool.log", std::ios::eek:ut);

// this tool.log name is not hardcoded
// so I may not know this name. only I've
// non-const ref to object logStream

std::eek:stream logStream(&fb);

// now, how can I get FILE* from this logStream ?

By "standard" do you mean C++ std? What're possible side
effect - portability?

Regards,
~ Soumen
 
A

Anand Hariharan

There is no fdopen function in standard C/C++; it's a Posix extension.
And even where your suggestion would work, you'd still have separate
buffers for the two, which could result in messages becoming scrambled.

What exactly does ios_base::sync_with_stdio buy us?

- Anand
 
J

James Kanze

What exactly does ios_base::sync_with_stdio buy us?

Time to go get a coffee:).

Seriously, it affects the standard streams only. If true, the
practical effect in most implementations will be that a lot of
unnecessary flushing will occur (but only on the standard
streams); better solutions are possible IF the FILE
implementation and the iostream implementation collaborate, but
this is rarely the case.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,982
Messages
2,570,190
Members
46,736
Latest member
zacharyharris

Latest Threads

Top