I want to make a variable format for my "write" statement. To do so, I wrote a small program (nvari is the variable):
program VariableFormat
implicit none
integer :: x = 1,y = 2, z = 3, i, nvari
double precision :: pi = 3.14
integer, allocatable :: var(:)
integer :: A(3) = (/1,2,3/)
character(100) :: fmt,fmt2,str1,str2,str3
print*, size(A)
allocate(var(size(A)))
do i = 1, size(A)
var(i) = A(i)
end do
nvari = 2
!
! first part
!
fmt = '(a,f4.2)'
write(*,fmt) "The value of pi is ", pi
!
! second part
!
write (str1, "(1A2,1I1,1A1,1I2,1A1)") "'(", 3, "I", 15, ","
print*, str1
write(str2,'(I10)') nvari
print*, str2
write (str3, "(1A1,1I2,1A2)") "I", 15, ")'"
print*, str3
fmt2 = trim(adjustl(str1))//trim(adjustl(str2))//trim(adjustl(str3))
print*, fmt2
write(*,fmt2) x,y,z,(var(i),i=1,nvari)
end program VariableFormat
First question: It can be seen that fmt2 is similar to fmt in the sense that in both we have '(X,Y)'. However, while the first part of the code is executed correctly, for the second part, I have the error:
At line 32 of file VariableFormat.F90 (unit = 6, file = 'stdout')
Fortran runtime error: Missing initial left parenthesis in format
'(3I15,2I15)'
I don't understand which parenthesis is missing as fmt2 is similar to fmt.
To execute my program I use the gfortran compiler: gfortran -o binary_VariableFormat VariableFormat.F90
and then:./binary_VariableFormat
Second question: Is there a way to write fmt2 in a more compact way?
This is perhaps more a misunderstanding about character variables and literal constants than about formats.
In
fmt = '(a,f4.2)'
we have the character variable's name (fmt
) on the left-hand side of the assignment and the value to assign on the right. '(a,f4.2)'
is a literal character constant and its value is given to fmt
.
The two, matching, '
's act as delimiters for the value of the constant: they are not themselves part of the value.1 The value of the literal constant is (a,f4.2)
. Go on, print the value of fmt
to check. (One actually has to do something quite different to get the value of a character variable with delimiters.)
A character value in a format must be something like (...)
: the first non-blank value must be a (
. Because you've set the value to be like '(...)'
the compiler is (quite rightly) complaining.
Where we have something like
write(str2,'(I10)') nvari
we are using this literal constant which has value (I10)
not '(I10)'
. If we instead had
write(str2,"'(I10)'") nvari
we'd see exactly the same complaint (or perhaps a complaint when compiling instead of running).
Finally, note that when using a FORMAT
statement (many here really don't like such things), we'd not have these delimiters at all:
format (I10) ! Correct
format '(I10)' ! Badly wrong
1 Similarly, if we have literal constants used like
complex :: a = (1., 2.)
integer :: i = INT(B'001')
the delimiters for the complex and BOZ literal constants are not part of the value. Equally in an array constructor like [0,1,2,3]
the square brackets are a delimiter part of the syntax rather than the value.