Is there an alternative to GETCWD() in Fortran 200

2019-02-17 20:15发布

问题:

The GNU Extension to the GNU Fortran compiler provides the subroutine GETCWD() that well, gets the current working directory. However, my code has to be portable to the ifort and nagfor compiler as well and I use F2003 features.

So, is there an alternative to GETCWD() for F2003 and later?

I have the standard here but it's quite sizeable and I've been going through it for a while now and haven't found anything useful...

回答1:

You can also use the ISO_C_Binding and call the corresponding C functions:

cwd.c:

#ifdef _WIN32
/* Windows */
#include <direct.h>
#define GETCWD _getcwd

#else
/* Unix */
#include <unistd.h>
#define GETCWD getcwd

#endif

void getCurrentWorkDir( char *str, int *stat )
{
  if ( GETCWD(str, sizeof(str)) == str ) {
    *stat = 0;
  } else {
    *stat = 1;
  }
}

test.F90:

program test
 use ISO_C_Binding, only: C_CHAR, C_INT
 interface
   subroutine getCurrentWorkDir(str, stat) bind(C, name="getCurrentWorkDir")
     use ISO_C_Binding, only: C_CHAR, C_INT
     character(kind=C_CHAR),intent(out) :: str(*)
     integer(C_INT),intent(out)         :: stat
    end subroutine
  end interface
  character(len=30)   :: str
  integer(C_INT)      :: stat

  str=''
  call getCurrentWorkDir(str, stat)
  print *, stat, trim(str)

end program

This code is valid for Windows and Unix-derivates (Linux, OSX, BSD, etc. )



回答2:

As noted in the comments, you can make use of get_environment_variable which is standard Fortran (e.g. F2008 13.7.67). This example program queries the value of $PWD, which should contain the directory your shell is in when you invoked the executable.

program test
 implicit none
 character(len=128) :: pwd
 call get_environment_variable('PWD',pwd)
 print *, "The current working directory is: ",trim(pwd)
end program

And its output:

casey@convect code % pwd
/home/casey/code
casey@convect code % so/getpwd 
 The current working directory is: /home/casey/code

This is standard Fortran, but its portability will be limited to Unix and Unix-like shells that set this variable.

Another option while standard but ugly (in my opinion) would be to use execute_command_line to run a command that can output the working directory to a temporary file (e.g. pwd > /tmp/mypwd), then reading that file.