Ответ 1
Если вы используете Intel fortran, для этого есть собственное расширение - вы можете включить существующую переменную в угловые скобки, чтобы действовать как спецификатор:
write(*,'(3f15.3,<nvari>f9.2)') x,y,z,(var(i),i=1,nvari)
Я хотел бы иметь форматированный оператор форматирования, отформатированный для зависимости от некоторой переменной. Например, я мог бы написать:
write(*,'(3f15.3,3f9.2)') x,y,z,(var(i),i=1,nvari)
где nvari = 3
. Но что, если в некоторых случаях у меня на самом деле есть 4 переменные (т.е. nvari = 4
). Я хотел бы написать что-то вроде этого:
write(*,'(3f15.3,nvari(f9.2))') x,y,z,(var(i),i=1,nvari)
Теперь nvari
может быть любым, и выход будет работать, как мне нравится. Как я могу сделать что-то вроде этой работы?
Если вы используете Intel fortran, для этого есть собственное расширение - вы можете включить существующую переменную в угловые скобки, чтобы действовать как спецификатор:
write(*,'(3f15.3,<nvari>f9.2)') x,y,z,(var(i),i=1,nvari)
Если ваш компилятор поддерживает его, '(3f15.3, *(f9.2))'
Если у вас есть старший компилятор, просто используйте большее число, чем у вас будут элементы для вывода, например, '(3f15.3, 999(f9.2))'
. Вам не нужно использовать формат.
В самых сложных случаях вы можете записать формат в строку и использовать это как свой формат:
write (string, '( "(3f15.3, ", I4, "(f9.2))" )' ) nvari
write (*, string ) x,y,z, (array(i), i=1,nvari)
При понимании форматов, включая реверсию формата, использование строковых форматов редко необходимо.
Вместо того, чтобы записывать формат непосредственно в оператор записи, также можно использовать символьную переменную.
character(len=32) :: my_fmt
my_fmt = '(3f15.3,3f9.2)'
write(*, my_fmt) x, y, z, (var(i), i = 1, nvari)
Теперь можно манипулировать символьной переменной, чтобы содержать требуемый счетчик повтора перед оператором записи, используя так называемую внутреннюю запись или запись во внутренний файл.
write(my_fmt, '(a, i0, a)') '(3f15.3,', nvari, 'f9.2)'
(Просто убедитесь, что объявленная длина my_fmt
достаточно длинная, чтобы содержать всю строку символов.)
Вы хотели написать что-то вроде этого:
write(*,'(3f15.3,nvari(f9.2))') x, y, z, (var(i), i=1,nvari)
На самом деле в стандарте Fortran есть старый трюк, который позволяет опустить nvari
, таким образом:
write(*,'(3f15.3,(f9.2))') x, y, z, (var(i), i=1,nvari)
или даже таким образом:
write(*,'(3f15.3,f9.2)') x, y, z, (var(i), i=1,nvari)
В стандарте указано, что последний дескриптор в формате неявно повторяется так часто, как это необходимо для размещения всех переменных в списке. Этот "последний дескриптор" может быть заключен в круглые скобки, так что последняя группа дескрипторов неявно повторяется, например:
write(*,'(3f15.3,(2x,f9.2))') x, y, z, (var(i), i=1,nvari)