Строка формата для вывода зависит от переменной

Я хотел бы иметь форматированный оператор форматирования, отформатированный для зависимости от некоторой переменной. Например, я мог бы написать:

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 может быть любым, и выход будет работать, как мне нравится. Как я могу сделать что-то вроде этой работы?

Ответ 1

Если вы используете Intel fortran, для этого есть собственное расширение - вы можете включить существующую переменную в угловые скобки, чтобы действовать как спецификатор:

  write(*,'(3f15.3,<nvari>f9.2)') x,y,z,(var(i),i=1,nvari)

Ответ 2

Если ваш компилятор поддерживает его, '(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)

При понимании форматов, включая реверсию формата, использование строковых форматов редко необходимо.

Ответ 3

Вместо того, чтобы записывать формат непосредственно в оператор записи, также можно использовать символьную переменную.

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 достаточно длинная, чтобы содержать всю строку символов.)

Ответ 4

Вы хотели написать что-то вроде этого:

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)