我有一个程序通过([a-z])
生成临时文件名,然后尝试通过tmpname
打开该文件。但是,当使用MinGW构建程序时,这始终会失败,但在使用VS2015构建时始终在同一台计算机上运行。这是一个简单的测试:
fopen
使用gcc构建和运行
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char** argv)
{
char fname[L_tmpnam];
if(!tmpnam(fname)) return EXIT_FAILURE;
printf("%s\n", fname);
FILE * f = fopen(fname, "wb");
if(!f) return EXIT_FAILURE;
fclose(f);
remove(fname);
return EXIT_SUCCESS;
}
输出
gcc test.c && a && echo ok || echo failed
通过
使用VS2015构建和运行\s4so.
failed
产生
cl test.c && test && echo ok || echo failed
其中%TMP%\s11w.0
ok
是TMP环境变量的值。
失败的原因很明显(MinGW不添加TMP文件夹,而是尝试写入用户没有写访问权限的当前驱动器的根目录)。但是,为什么会这样呢?我错过了一个电话,还是这个错误?
答案 0 :(得分:1)
然而,为什么会发生这种情况?我错过了一个电话,还是这个错误?
标准未指定文件的位置。所以这不是一个错误,它是tmpnam
BTW:在Visual C ++ 2015之前,Visual C ++也使用了驱动器的根目录。见https://msdn.microsoft.com/en-us/library/bb531344.aspx
答案 1 :(得分:0)
查看MSDN
如果定义了TMP环境变量并将其设置为有效的目录名,则将为TMP指定的目录生成唯一的文件名。
如果未定义TMP环境变量或将其设置为不存在的目录名称,
_tempnam
将使用dir参数作为生成唯一名称的路径如果未定义TMP环境变量或将其设置为不存在的目录名称,并且dir为NULL或设置为不存在的目录名称,{ {1}}将使用当前工作目录生成唯一名称。目前,如果TMP和dir都指定了不存在的目录名称,则_tempnam函数调用将失败。
强调我的
似乎在Windows上重新定义了该行为。
这不是我的man
定义的linux行为创建的路径名具有目录前缀
_tempnam
。 (都 L_tmpnam和 P_tmpdir在P_tmpdir
中定义,就像<stdio.h>
一样 如下所述。)
强调我的
在我的系统TMP_MAX
上设置为P_tmpdir
,代码效果良好,返回"/tmp"
此外,查看stdio.h,你会发现P_tmpdir的声明有条件:
/tmp/something
处理这些设置:在我的#if defined __USE_SVID || defined __USE_XOPEN
/* Default path prefix for `tempnam' and `tmpnam'. */
# define P_tmpdir "/tmp"
#endif
文件features.h
上定义为__USE_SVID
简单来说:你必须照顾平台,因为windows的行为与linux不同