tmpnam创建的文件名的fopen在mingw上失败

时间:2016-08-10 09:07:42

标签: c++ c windows mingw mingw-w64

我有一个程序通过([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文件夹,而是尝试写入用户没有写访问权限的当前驱动器的根目录)。但是,为什么会这样呢?我错过了一个电话,还是这个错误?

2 个答案:

答案 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不同