Format string for output dependent on a variable

2019-01-07 19:01发布

问题:

I would like to have a Fortran write statement formatted to depend on some variable. For example, I could write:

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

where nvari = 3. But, what if, in some cases, I actually have 4 variables (i.e. nvari = 4). I would like to write something like this:

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

Now, nvari can be anything and the output will work as I like. How can I make something like this work?

回答1:

If you are using Intel fortran, it has a proprietary extension for this -- you can include an existing variable in angle brackets to act as a specifier:

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


回答2:

If you compiler supports it, '(3f15.3, *(f9.2))'

If you have an older compiler, just use a larger number than you will have items to output, e.g., '(3f15.3, 999(f9.2))'. You don't have to use up the format.

For the most complicated cases you can write a format to a string and use that as your format:

write (string, '( "(3f15.3, ", I4, "(f9.2))" )' )  nvari
write (*, string )  x,y,z, (array(i), i=1,nvari)

With the understanding of formats, including format reversion, the use of string formats is rarely necessary.



回答3:

Instead of writing the format directly in the write statement, it's also possible to use a character variable.

character(len=32) :: my_fmt
my_fmt = '(3f15.3,3f9.2)'
write(*, my_fmt) x, y, z, (var(i), i = 1, nvari)

Now it is possible to manipulate the character variable to contain the wanted repeat count before the write statement, using a so-called internal write, or write to internal file.

write(my_fmt, '(a, i0, a)') '(3f15.3,', nvari, 'f9.2)'

(Just make sure the declared length of my_fmt is long enough to contain the entire character string.)



回答4:

You wanted to write something like this:

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

In fact, there is an old trick in the Fortran standard that allows you to omit the nvari, thus:

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

or even thus:

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

The standard says that the last descriptor in the format is implicitly repeated as often as is necessary to accommodate all of the variables in the list. That 'last descriptor' could be parenthesized such that the last group of descriptors is implicitly repeated, for example:

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