如何使用Fortran获取可执行文件的位置?

时间:2010-10-26 08:08:42

标签: path executable fortran

我有一个用Fortran 90/95编写的程序;在调用之后,它总是读取某个数据文件。为了方便用户,我希望他们只需将此文件放在与可执行文件本身相同的目录中,而不必设置一些环境变量/ extend $ PATH,并且不强制它们为此目的使用某个目录。程序应该“简单地”在存储它本身的目录中查找文件,而不是在运行它的目录中查找。然而,到目前为止,我未能找到解决这个问题的方法。我尝试使用

getarg(0,path)

但这只给了我用来调用程序的字符串,而不是它的绝对路径。

如果您有任何建议,也有关于变通方法的建议,请随时回复。非常感谢提前!

4 个答案:

答案 0 :(得分:2)

要求二进制文件位于某个特定目录中,这让我感到很奇怪。只要在PATH上找到二进制文件,就可以使用东西了。你可以做的是尝试从当前工作目录中读取数据文件,即用户在启动程序时所在的目录。

我不想要求用户始终复制数据文件,您可以搜索一些“默认”位置,然后使用找到该文件的第一个位置,例如当前的工作目录,然后$ HOME / .your_program / file.dat,最后是/usr/local/share/your_program_name/file.dat,或类似的东西。

编辑但是,如果您希望继续沿着这个错误的路径继续,至少在Linux上你可以使用readlink()(你可能需要为此创建一个C包装器,请参阅ISO C在最近的Fortran编译器中绑定)来检查/ proc / self / exe符号链接。

顺便说一句,GETARG不是Fortran标准的一部分,因此您依赖于供应商扩展(无可否认地得到了广泛的支持)。从Fortran 2003开始,执行此操作的标准功能是GET_COMMAND_ARGUMENT内在函数。

答案 1 :(得分:0)

我认为这在fortran中是一个难以解决的问题,我认为你的方法是正确的(将数据文件放在与可执行文件相同的目录中)。 Fortran需要与python的

类似的东西
os.path.dirname(os.path.realpath(sys.argv[0]))

不幸的是,Fortran对于I / O来说非常糟糕,你的问题只突出了一个小方面。

以防万一其他人跳过枪并认为这是一个微不足道的问题 - 考虑一下你不知道人们将要运行这个可执行文件的操作系统,你不知道可执行文件的名称。

我的,可能很糟糕,解决方法是使用INDEX来查找“/”。如果它返回非零然后用户“必须”在linux系统上,那么使用INDEX删除可执行文件的名称,你就得到了你的路径。然后查找“\”,如果INDEX找到了某些内容,则假设OS=windows并删除可执行文件。

答案 2 :(得分:0)

canavanin,您在此期间找到了解决方案吗?在g77中getarg(0,path)以完整路径传递可执行文件,但不在gfortran中传递。然而,gfortran的这个缺点似乎只是针对Windows的。 See Here演示了getarg在bash shell中的功能......

--- corection: 我现在发现问题不是GFORTRAN vs G77,而是具体的构建。 DJGPP(DOS端口)发行版的最新GCC / GFORTRAN版本(4.54)使getarg(0,path)在[executable] .exe前面提供完整路径。分隔字符是“/”而不是“\”。

答案 3 :(得分:-1)

在Digital Visual Fortran(等)中,在Windows中,我这样做:

  SUBROUTINE GetFullExeName(FULLNAME,L)  


!******************************************************************************  
!  
!  Gets the full name of the current executing program.  
!  
!******************************************************************************  
      USE DFWIN  
      CHARACTER*(*) FULLNAME          ! full name  
      INTEGER       L                 ! length  
      L= GetModuleFileName(NULL,FULLNAME,LEN(FULLNAME))   ! windows API  
      FULLNAME(L+1:) = ' '  
      END