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).