Tutorial :mixing C and C++ file operations



Question:

I am writing a file splitting program, to assist with using large files with iPod notes. I want to use tmpfile() in cstdio but it returns a file* not an fstream object. I know it's not possible in standard C++ but does anyone know any libraries that work well with the standard that have the ability to convert a FILE* to an std::fstream object? Or, if not is tmpfile() functionality available in the standard, or another library?

Thanks!

My OS is Windows XP and I use either Dev-C++ 4.9.9.2 or MS Visual Studio 2008 as my compiler.


Solution:1

If all you want is a temporary file, use tmpnam() instead. That returns char* name that can be used for a temporary file, so just open a fstream object with that name.

Something like:

#include <cstdio>  #include <fstream>    ...  char name[L_tmpnam];  tmpnam(name);    //also could be:  //char *name;  //name = tmpnam(NULL);    std::fstream file(name);  

You do have to delete the file yourself, though, using remove() or some other method.


Solution:2

You can use the benefits of c++ streams by pumping your data via the << syntax into a std::stringstream and later write it the .str().c_str() you get from it via the the C-API to the FILE*.

  #include <sstream>  #include <cstdio>  #include <string>    using namespace std;    int main()  {    stringstream ss;    ss << "log start" << endl;      // ... more logging      FILE* f_log = fopen("bar.log", "w");    string logStr =  ss.str();    fwrite(logStr.c_str(), sizeof(char), logStr.size(), f_log);     fclose(f_log);      return 0;  }  


Solution:3

Even if you manage to convert a FILE* to an std::fstream, that won't work as advertised. The FILE object returned by tmpfile() has a special property that, when close()'d (or when the program terminates), the file is automatically removed from the filesystem. I don't know how to replicate the same behavior with std::fstream.


Solution:4

You could use tmpnam mktmp to obtain a temporary file name, open it with a stream and then delete it with remove.

char *name;  ifstream stream;    name = mktmp("filename");  stream.open(name);  //do stuff with stream here.    remove(name);//delete file.  


Solution:5

Instead of using std::fstream, you could write a simple wrapper class around FILE*, which closes it on destruction. Should be quite easy. Define operators like << as necessary. Be sure to disallow copying, to avoid multiple close() calls.


Solution:6

g++ has __gnu_cxx::stdio_filebuf and __gnu_cxx::stdio_sync_filebuf, in ext/stdio_filebuf.h and ext/stdio_sync_filebuf.h. It should be straight-forward to extract them from libstdc++ if your compiler is not g++.


Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Previous
Next Post »