_tempnam() always returns a filename in the "c:\\temp" directory, regardless of the parameters. This example was extracted from MSDN. I need to generate a unique filename in a directory other than c:\temp -- any ideas how to do that other than writing my own function? maybe a c++ solution?

Note this is one of may examples where Microsoft uses void main() instead of int main() :evil: Not that I mind -- but can be confusing to newbes.

Thanks

#include <stdio.h>

void main( void )
{
   char  *name2;


   /* Create a temporary filename in temporary directory with the
    * prefix "stq". The actual destination directory may vary
    * depending on the state of the TMP environment variable and
    * the global variable P_tmpdir.
    */
   
   if( ( name2 = _tempnam( "c:\\h", "stq" ) ) != NULL )
   {
      printf( "%s is safe to use as a temporary file.\n", name2 );
	  FILE*fp = fopen(name2,"wt");
	  fprintf(fp,"Hello World\n");
	  fclose(fp);
   }
   else
      printf( "Cannot create a unique filename\n" );
}

Dani AI

Generated

Short summary and practical fix for the observed behavior (as discussed by , and ): the CRT helpers will prefer the system temp environment (TMP/TEMP), which is why _tempnam kept returning a path under C:\Temp until those vars were changed. For reliably getting a unique name in a specific directory, prefer the Win32 APIs or the safer CRT/C++ helpers rather than relying on _tempnam/tmpnam/_mktemp.

A simple, robust Windows approach is to call GetTempFileName (give it the desired directory in lpPathName). When called with uUnique == 0 it will produce a unique name and create an empty file (avoiding the classic time-of-check/time-of-use race). See the API notes and the “creating and using temporary files” guidance for details.
GetTempFileName (and GetTempPath/GetTempPath2 to find temp dirs). (learn.microsoft.com)

Security and best-practice notes: the old functions tmpnam/_mktemp/_tempnam are error-prone and considered unsafe for new code; prefer their “_s” secure variants if sticking with CRT, or use CreateFile with CREATE_NEW (atomic create) on a GUID-based name to guarantee exclusive creation. Also, if creating many files, consider GUIDs or appending the process id to reduce collisions. See Microsoft’s secure-CRT guidance and CreateFile docs for the correct flags.
Security-enhanced CRT functions. (learn.microsoft.com)

If a C++-style solution was intended (as asked), C++17’s std::filesystem provides temp_directory_path() to locate the system temp directory; combine that with a GUID or the Win32 CreateFile CREATE_NEW pattern to make a safe unique file in any directory. For quick troubleshooting: inspect TMP/TEMP (or P_tmpdir) in the environment if a CRT helper keeps returning the “wrong” folder — that’s what caused the original surprise in this thread. (docs4dev.com)

Code hint (illustrative): use GetTempFileName with the directory wanted, then open the returned path (it already exists when uUnique==0), or generate a GUID and call CreateFile with CREATE_NEW for an atomic create.

Recommended Answers

All 4 Replies

>I need to generate a unique filename in a directory other than c:\temp
Is this a directory that you specify or just any directory other than C:\temp? If it's the latter then tmpnam will create the file in the local directory. If it's the former then you're SOL and need to do it manually.

Is this a directory that you specify.

A directory I specify, as shown in the example program I posted. This might be another famous example where MSDN is wrong.

I decided to create unique filenames another way by using the current system time from GetLocalTime().

Thanks anyway for your reply.

Ah! Ha! I overlooked that -- I have a temp and tmp environment variables.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.