How to create a temporary text file in C++?
Asked Answered
C

8

33

I'm trying to create a temporary text file in C++ and then delete it at the end of the program. I haven't had much luck with Google.

Could you tell me which functions to use?


The answers below tell me how to create a temp file. What if I just want to create a file (tmp.txt) and then delete it? How would I do that?

Cordate answered 20/6, 2009 at 20:34 Comment(4)
and then delete it at the end of the file ?R
cplusplus.com/doc/tutorial/filesAffirm
Yes. The temporary file will only contain temporary data. The output will be written to an existing output.txt file.Cordate
For directories: #3380456Budwig
R
25

Maybe this will help

FILE * tmpfile ( void );

http://www.cplusplus.com/reference/clibrary/cstdio/tmpfile/

Open a temporary file

Creates a temporary binary file, open for update (wb+ mode -- see fopen for details). The filename is guaranteed to be different from any other existing file. The temporary file created is automatically deleted when the stream is closed (fclose) or when the program terminates normally.

See also

char * tmpnam ( char * str );

Generate temporary filename

A string containing a filename different from any existing file is generated. This string can be used to create a temporary file without overwriting any other existing file.

http://www.cplusplus.com/reference/clibrary/cstdio/tmpnam/

R answered 20/6, 2009 at 20:39 Comment(7)
It is worth mentioning that there might be issues with tmpfile() and tmpnam() in some contexts e.g., codeproject.com/KB/web-security/TemporaryFileSecurity.aspxDocilla
Tmpfile, of course, has the problem of returning a C file handle, not a c++ stream.Rapport
@rlbond: Indeed, thats why I included tmpnam.R
it's very important to note that tmpnam() is not to be used. its man page says: "Never use this function. Use mkstemp(3) or tmpfile(3) instead."Thaine
Where exactly is the temporary file created?Jungian
The problem is, the second one is considered unsafe and gives you a warning, and the first one you can't get the name of and delete after use.Coppock
tmpnam, while part of the POSIX standard, is deprecated, and should be discouraged. See this SO question.Coppock
C
28

Here's a complete example:

#include <unistd.h>

int main(void) {
  char filename[] = "/tmp/mytemp.XXXXXX"; // template for our file.        
  int fd = mkstemp(filename);    // Creates and opens a new temp file r/w.
                                 // Xs are replaced with a unique number.
  if (fd == -1) return 1;        // Check we managed to open the file.
  write(fd, "abc", 4);           // note 4 bytes total: abc terminating '\0'
  /* ...
     do whatever else you want.
     ... */
  close(fd);
  unlink(filename);              // Delete the temporary file.
}

If you know the name of the file you want to create (and are sure it won't already exist) then you can obviously just use open to open the file.

tmpnam and tmpfile should probably be avoided as they can suffer from race conditions - see man tmpfile(3) for the details.

Catabasis answered 20/6, 2009 at 21:1 Comment(3)
The Linux man page for mkstemp(3) says that the last 6 characters in filename must be XXXXXX. See kernel.org/doc/man-pages/online/pages/man3/mkstemp.3.htmlDocilla
Hmm, the OS X manpage for mkstemp says you can have a variable number of XXXs. however in the interests of clarity (and 'cos most people are probably using Linux) I've changed the above example.Catabasis
Actually it's mktemp and tmpnam that suffer from the race conditions you mention, not tmpfile. tmpfile returns the a C file handle, so you won't get a C++ stream, but you don't get a race condition either. I think the man pages you want to reference above are for tmpname(3) kernel.org/doc/man-pages/online/pages/man3/tmpnam.3.html and mktemp kernel.org/doc/man-pages/online/pages/man3/mktemp.3.htmlBirr
R
25

Maybe this will help

FILE * tmpfile ( void );

http://www.cplusplus.com/reference/clibrary/cstdio/tmpfile/

Open a temporary file

Creates a temporary binary file, open for update (wb+ mode -- see fopen for details). The filename is guaranteed to be different from any other existing file. The temporary file created is automatically deleted when the stream is closed (fclose) or when the program terminates normally.

See also

char * tmpnam ( char * str );

Generate temporary filename

A string containing a filename different from any existing file is generated. This string can be used to create a temporary file without overwriting any other existing file.

http://www.cplusplus.com/reference/clibrary/cstdio/tmpnam/

R answered 20/6, 2009 at 20:39 Comment(7)
It is worth mentioning that there might be issues with tmpfile() and tmpnam() in some contexts e.g., codeproject.com/KB/web-security/TemporaryFileSecurity.aspxDocilla
Tmpfile, of course, has the problem of returning a C file handle, not a c++ stream.Rapport
@rlbond: Indeed, thats why I included tmpnam.R
it's very important to note that tmpnam() is not to be used. its man page says: "Never use this function. Use mkstemp(3) or tmpfile(3) instead."Thaine
Where exactly is the temporary file created?Jungian
The problem is, the second one is considered unsafe and gives you a warning, and the first one you can't get the name of and delete after use.Coppock
tmpnam, while part of the POSIX standard, is deprecated, and should be discouraged. See this SO question.Coppock
D
6

This may be a little off-topic because the author wanted to create a tmp.txt and delete it after using it, but that is trivial - you can simple open() it and delete it (using boost::filesystem of course).

mkstemp() is UNIX-based. With Windows you use GetTempFileName() and GetTempPath() to generate a path to a temp file. Sample code from MSDN:

http://msdn.microsoft.com/en-us/library/aa363875%28VS.85%29.aspx

Dempstor answered 4/3, 2010 at 8:15 Comment(0)
P
6

On Linux (starting with kernel 3.11), there's flag to open(2) O_TMPFILE that creates a temporary file that doesn't have a name (i.e. it doesn't show up in the filesystem). This has a few interesting features:

  • No worries about unique names, it's just an inode, there is no name.
  • No race conditions during creation (e.g. symlink attacks).
  • No stray files if your app crashes, it's always automatically deleted.
Protozoon answered 6/10, 2014 at 20:35 Comment(1)
Minimal runnable example: #4509498 I wonder if glibc can use that to implement tmpfile, but lazy to check now.Budwig
I
3

I wonder why most of you guys showed him the C way of doing it instead of the C++ way.
Here's fstream.
Try that, deleting a file is OS depended but you can use boost.filesystem to make things easy for you.

Internee answered 20/6, 2009 at 22:28 Comment(1)
That's probably because the OP asked for a temporary file, and there are no standard C++ mechanisms for creating a unique filename. There is nothing in libstdc++ or boost that truly replaces mkstemp().R
F
2

If you need a named file (for example, so you can pass the name to another process, perhaps a compiler or editor), then register a cleanup function that removes the file with atexit(). You can use either C++ <iostream> or C FILE * (<cstdio>) to create the file. The not completely standard but widely available mkstemp() function creates a file and tells you its name as well as returning a file descriptor (a third I/O mechanism); you could use the fdopen() function to convert the file descriptor into a FILE *.

If you don't need a named file a C-style FILE * is OK, then look at tmpfile() as suggested by @Tom.

Freshet answered 20/6, 2009 at 20:51 Comment(0)
A
1

A clean, portable and non-deprecated way of creating a temporary file is provided by Boost:

auto temporary_file = boost::filesystem::temp_directory_path() / boost::filesystem::unique_path();
Ajmer answered 19/12, 2020 at 18:35 Comment(0)
P
0

Well, assuming you have been successful in creating the temporary file, you can use the remove function to delete it.

The function is declared in stdio.h -

#include <stdio.h>

int remove(const char *pathname);

For example, if you want to delete a file named myfile.txt the code will be

#include<stdio.h>

int main()
{
  if(remove("myfile.txt") == -1)
  {
    fprintf(stderr,"Remove failed");
    exit(EXIT_FAILURE);
  }
  exit(EXIT_SUCCESS);
}

I hope by now, you already know how to create the temp file, so this should resolve your query. Hope it helps.

Palestine answered 20/6, 2009 at 21:9 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.