Print a Fortran 2D array as a matrix
I have an array that is currently a 3x3. When I print out the characters, I get the results printed in a wrap-around-line style. I am hoping to print a square matrix that is more readable instead of XXXXXXXXXXXXX on a single line. Is it possible with a do loop?
I have the following:
CHARACTER(len=1) :: Grid(2,2)
Grid = "*"
Print *, Grid
Solution 1:
Depending on the output format you desire, you would not necessarily need a do-loop, here is the simplest:
program simple
implicit none
CHARACTER(len=1) :: Grid(2,2)
Grid = reshape( ["1","2","3","4"] , shape=shape(Grid) )
write( * , "(A)" ) Grid
end program simple
The line with reshape
, uses the Fortran >2003 array constructor syntax []
. So make sure your compiler settings already is set to Fortran 2008 standard. Otherwise, simply replace []
with the old array constructor syntax (//)
.
If you want each row to be printed on a different line, then looping would be necessary, at least, an implied do-loop,
program simple
implicit none
integer :: i,j
integer, parameter :: n=2
CHARACTER(len=1) :: Grid(n,n)
Grid = reshape( ["1","2","3","4"] , shape=shape(Grid) )
write( * , "(*(g0))" ) ( (Grid(i,j)," ",j=1,n), new_line("A"), i=1,n )
end program simple
The above version, I believe, avoids the unnecessary temporary array created by the compiler to store the non-contagious array section Grid(i,:)
, before printing it to the output. The g0
edit descriptor is a handy feature of Fortran 2008. So make sure you compiler supports Fortran 2008 standard.
Solution 2:
Something like printing an array row at a time:
program printarray
implicit none
CHARACTER(len=1) :: Grid(3,2)
integer :: i
Grid = "x"
do i = 1, ubound(Grid, 1)
print *, Grid(i, :)
end do
end program printarray
Alternatively, one can depend on the fact that if there are more stuff to write than there are elements in the format specifier, then it switches to a new line. So, something like:
program printarray2
implicit none
CHARACTER(len=1) :: Grid(4,2)
character(len=10) :: fmt
Grid = "x"
write(fmt, '(A,I0,A)') '(', ubound(Grid, 2), 'A)'
write(*, fmt) transpose(grid)
end program printarray2
There's a slight trickiness here in that printing the entire array prints it in memory order, which is column major in Fortran. That's why you have to transpose it (and why you take the ubound of dimension 2 and not 1 as in the first example when creating the format string).