\
Windows や/
Unix、Fortranなどの現在のオペレーティング システムのファイル セパレータを実行時に取得する方法を教えてください。
4 に答える
Fortran 2003 標準組み込み手続きGET_ENVIRONMENT_VARIABLE
を使用して、このようなことを行うことができます。例:
CHARACTER(LEN=99999) :: path
CHARACTER(LEN=1) :: path_separator
CALL GET_ENVIRONMENT_VARIABLE('PATH',path)
path_separator=path(1:1)
WRITE(*,*)'Path separator is ',path_separator
END
このプログラムは、UNIX または Linux のパス区切りとして「/」を出力します。これは、他の環境変数からも取得できます。この例は、UNIX/Linux 用に組み込まれていることに注意してください。Windows の「\」などを抽出するには、少し異なるロジックが必要ですが、私はこのシステムに慣れていません。Win95の頃は「c:\.....」みたいなのがあった記憶がありますので、Windowsの場合は「\」を検索するのが一般的ですpath(3:3)
。
お役に立てれば。
私の知る限り、Fortran 標準では、ファイル システムのパス セパレータについて何も述べていません。私が提案できる最善の方法は、適切なセパレーターを定義するマクロを定義することです。例えば
#if __unix__
character(len=1), parameter :: path_sep='/'
#elif _WIN32
character(len=1), parameter :: path_sep='\'
#else
#error "path_sep not defined. Set this constant for your system."
#endif
ただし、 Windows ではパス区切り文字としてまたはを使用できる/
\
ので (試してみてください!)、ほとんどのシステムでは、パス区切り文字で特別なことをする必要はありません。
実行時にパス区切りを決定する必要がないことに注意してください。実行する新しいシステムごとに Fortran ソースを再コンパイルする必要があるため、新しいシステムごとにコンパイル時に正しいパス区切り文字が指定されていることを確認するだけで済みます (パス区切り文字はプログラムの実行間で変更されません)。同じシステム上)。
上記のようなプリプロセッサ マクロを使用することは、これを行うための明白な方法です#elif
。コードを移植する新しいシステムごとに新しい句を追加するだけです。これは、他の回答が示唆するような特定の環境変数をチェックする picemeal ソリューションを導入するよりもはるかに簡単です。
パス セパレータを指定するだけでなく、オペレーティング システム環境の他の側面のパラメータも設定する必要がある場合があります。たとえば、現在のディレクトリ文字と親ディレクトリの文字 ( Windows と POSIX システムではそれぞれ と ) .
。..
最後に、プリプロセッサは、使用しているシステムを示す広く使用されているマクロを定義し__unix__
、_WIN32
使用しているシステムに応じて、ほとんどのコンパイラで設定する必要があることに注意してください。設定されていない場合は、通常、フラグを使用する-D__unix__=1
か-D_WIN32=1
、ソースをコンパイルするときにこれらのマクロのいずれかを設定できます。-cpp
(gfortran) または(ifortran) コマンド ライン オプションを使用してコードを前処理する-fpp
か、ソース ファイルの拡張子を から.f
に、.F
または から.f90
に変更します.F90
。
IROボットの提案に従って、新しい環境変数を作成できます。
export DELIMITER='/'
UNIXで
次に、「\」だけを使用して、対応する変数をWindowsで作成します。これで、準備は完了です。
Windowsでグローバル変数を設定したくない場合、または設定する権限がない場合は、以下を.batファイルに入れてください。
set DELIMITER=\
setの詳細については、http: //www.ss64.com/nt/set.htmlを参照してください 。setを使用する場合は、CMDからFortranプログラムを実行する必要がある場合があります。
最後に、次のものをFortranファイルに入れます
CHARACTER :: delimiter
CALL get_environment_variable('DELIMITER',delimiter)
私はむしろ上記の 4 の解決策を好みますが、1 つの変更があります。
function delimiter_detect() result(delim)
character(LEN=1) :: delim
character(LEN=258) :: path
integer :: ii, stat_out
call GET_ENVIRONMENT_VARIABLE('HOME',path,status=stat_out)
if (stat_out/=0) go to 999
! xxx path='xx\' ! alternate test
do ii=1, 258
delim=path(ii:ii)
if (delim=='/'.or.delim=='\') return
! ... Note: emacs does not recognize the second delimiter test
enddo
999 continue
write(*,'(1x,a/1x,a/1x,a)') 'Could not obtain home directory path.', &
'Restart program and manually insert path', &
'to folder/directory containing input files.'
stop
end function delimiter_detect
とはいえ、Windows OS でこの概念をテストしたことはありません。