Problem
You have to store some stuff on disk temporarily, and you don't want to have to write a routine that generates a unique name yourself.
Solution
Use either the tmpfile or tmpnam functions, declared in . tmpfile returns a FILE* that is already opened for writing, and tmpnam generates a unique filename that you can open yourself. Example 10-13 shows how to use tmpfile.
Example 10-13. Creating a temporary file
#include #include int main( ) { FILE* pf = NULL; char buf[256]; pf = tmpfile( ); // Create and open a temp file if (pf) { fputs("This is a temp file", pf); // Write some data to it } fseek(pf, 5, SEEK_SET); // Reset the file position fgets(buf, 255, pf); // Read a string from it fclose(pf); std::cout << buf << ' '; }
Discussion
There are two ways to create a temporary file; Example 10-13 shows the first way. The function tmpfile is declared in , takes no parameters, and returns a FILE* if successful, NULL if not. The FILE* is the same type you can use with the C input/output functions fread, fwrite, fgets, fputs, etc. tmpfile opens the temporary file in "wb+" mode, which means you can write to it or read from it in binary mode (i.e., the characters are not interpreted as they are read). When your program terminates normally, the temporary file created by tmpfile is automatically deleted.
This may or may not work for you depending on your requirements. You will notice that tmpfile does not give you a filenamehow do you pass the file to another program? You can't; you'll have to use a similar function instead: tmpnam.
tmpnam doesn't actually create a temporary file, it just creates a unique file name that you can use to go open a file using that name yourself. tmpnam takes a single char* parameter and returns a char*. You can pass in a pointer to a char buffer (that has to be at least as big as the macro L_tmpnam, also defined in ), where tmpnam will copy the temporary name, and it will return a pointer to the same buffer. If you pass in NULL, tmpfile will return a pointer to a static buffer that contains the filename, which means that subsequent calls to tmpnam will overwrite it. (See Example 10-14.)
Example 10-14. Creating a temporary filename
#include #include #include #include int main( ) { char* pFileName = NULL; pFileName = tmpnam(NULL); // Right here is where another program may get the same temp // filename. if (!pFileName) { std::cerr << "Couldn't create temp file name. "; return(EXIT_FAILURE); } std::cout << "The temp file name is: " << pFileName << ' '; std::ofstream of(pFileName); if (of) { of << "Here is some temp data."; of.close( ); } std::ifstream ifs(pFileName); std::string s; if (ifs) { ifs >> s; std::cout << "Just read in "" << s << "" "; ifs.close( ); } }
But there is something important you should know about tmpnam. It has a race condition whereby more than one process may generate the same filename if one calls tmpname and the other calls tmpname before the first process opens the file. This is bad for two reasons. First, a malicious program can do this to intercept the data in a temporary file, and second, an unsuspecting program can get the same filename and simply corrupt or delete data.
Building C++ Applications
Code Organization
Numbers
Strings and Text
Dates and Times
Managing Data with Containers
Algorithms
Classes
Exceptions and Safety
Streams and Files
Science and Mathematics
Multithreading
Internationalization
XML
Miscellaneous
Index