Получить разделитель файлов в Фортране - PullRequest
4 голосов
/ 24 декабря 2011

Подскажите, пожалуйста, как получить разделитель файлов в текущей операционной системе, например, \ в Windows и / в Unix в Fortran во время выполнения.

Ответы [ 4 ]

4 голосов
/ 24 декабря 2011

Вы можете использовать стандартную внутреннюю процедуру 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).

Надеюсь, это поможет.

3 голосов
/ 24 декабря 2011

Насколько я знаю, стандарт 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) или -fpp (ifort) или изменения расширений исходных файлов с .f на .F или с .f90 на .F90.

1 голос
/ 29 декабря 2011

Следуя совету IRO-бота, вы можете создать новую переменную окружения, например,

export DELIMITER='/'

в unix

Теперь создайте соответствующую переменную в Windows, просто с помощью '\', ивсе готово.

Если вы не хотите устанавливать глобальную переменную в Windows или не имеете прав для этого, поместите следующее в файл .bat

set DELIMITER=\

Подробнее о наборе см. http://www.ss64.com/nt/set.html Возможно, вам придется запускать программу fortran из CMD при использовании set.

Наконец, поместите следующее в ваш файл fortran

CHARACTER :: delimiter
CALL get_environment_variable('DELIMITER',delimiter)
0 голосов
/ 04 октября 2015

Я предпочитаю решение 4 выше, но с одной модификацией:

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.

...