C++ equivalent for tmpfile()

Mar 24, 2013 at 11:42am
http://cplusplus.com/reference/cstdio/tmpfile/

Searching the Reference, I couldn't find a C++ stream equivalent for the above.
Mar 24, 2013 at 12:51pm
Well, I didn't find one. You can always write tempfile class yourself and use it in all future projects.
Here what can be used to create it in Windows:
http://msdn.microsoft.com/en-us/library/windows/desktop/aa364992%28v=vs.85%29.aspx
http://msdn.microsoft.com/en-us/library/windows/desktop/aa364991%28v=vs.85%29.aspx
Mar 24, 2013 at 1:50pm
As far as I know, std::tmpfile is the only way to get both atomic unique name generation / file opening and auto-deletion.

I would write a streambuf wrapper, it's a very legitimate case for one. Or, to write less code, you could use fileno() (on a POSIX system) or whatever Windows has to get a HANDLE from FILE*, and then construct a boost.iostreams file_descriptor stream.
Mar 24, 2013 at 3:27pm
I would write a streambuf wrapper, it's a very legitimate case for one.

Please give more detail, because I don't understand how and why.

Do you suggest coding a class that uses a FILE internally, and can be used in place of a std::streambuf?
Mar 24, 2013 at 3:50pm
Yes: a class derived from streambuf with a FILE* data member, obtained in its constructor by calling std::tmpfile. That's just how you add new stream types to the streams library. As for detail, JLBorges likes to link to this tutorial: http://www.mr-edd.co.uk/blog/beginners_guide_streambuf , I like boost.iostreams: http://www.boost.org/doc/libs/release/libs/iostreams/doc/tutorial/writing_devices.html for simple cases like this.
Mar 24, 2013 at 11:54pm
Thanks for the links and help, but I'm giving up.

I had begun writing a TmpFileSb class, but I stopped shortly after, because of the overwhelming feeling that I was doing someone else's work.
Mar 30, 2013 at 5:36pm
Google around "stdiostream" and "stdiobuf" to find the things other people have already done. At one time, I think there was one in Boost...

Here's mine:
http://www.cplusplus.com/forum/articles/22316/
(It is unfinished, alas... you'll need to pay attention to the two bugs in there.)

From a thread about the same thing (using FILE* the C++ way):
http://www.cplusplus.com/forum/beginner/22230/#msg116635 (without FILE*)
http://www.cplusplus.com/forum/beginner/22230/#msg116842 (using my stdiostream)

Hope this helps.

[edit] If I ever get time I'd like to fix those two bugs and put this in an actual code article... If you fix it I'll put your name in the header.
Last edited on Mar 30, 2013 at 5:36pm
Mar 30, 2013 at 8:03pm
Thanks Duoas. I'll need a good tmpfile() component when/if I attempt the Burrows-Wheeler Transform, a topic for another article.
Mar 31, 2013 at 4:29pm
Duoas, I'm trying to fix the bugs, but so far I failed.

You rely on std::basic_iostream to delete the stream buffer pointer you feed it. But it doesn't? This is why your destructor isn't called. I think.

http://cplusplus.com/reference/istream/basic_iostream/~basic_iostream/
Mar 31, 2013 at 5:09pm
libstdc++ specific (AFAIK, works only for char and wchar_t):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <cstdio>
#include <iostream>
#include <string>
#include <ext/stdio_filebuf.h> // libstdc++ specific

int main()
{
    __gnu_cxx::stdio_filebuf<char> tmpfile_buf( std::tmpfile(),
                            std::ios::in|std::ios::out|std::ios::binary ) ;
    std::iostream temp_fstream( &tmpfile_buf ) ;

    // use temp_fstream
    temp_fstream << 12345 << ' ' << 67.89 << "Hello World\n" ;

    temp_fstream.seekg(0) ;
    int i = 0 ; temp_fstream >> i ;
    double d = 0 ; temp_fstream >> d ;
    std::string str ; std::getline( temp_fstream, str ) ;
    std::cout << i << '\n' << d << '\n' << str << '\n' ;
}


Portable: boost::iostreams::file_descriptor with fileno() (POSIX) or _fileno() (Windows)
Last edited on Mar 31, 2013 at 5:14pm
Topic archived. No new replies allowed.