4

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
Mateen Ulhaq
  • 24,552
  • 19
  • 101
  • 135
Sunny
  • 67
  • 1
  • 1
  • 6

3 Answers3

5

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.

Scientist
  • 1,767
  • 2
  • 12
  • 20
4

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

janneb
  • 36,249
  • 2
  • 81
  • 97
  • Your second method seems astounding, can you explain to me how it works/refer to me a source where I can read more about its usage? – amzon-ex Oct 13 '20 at 12:14
  • 1
    The first write statement creates a format string with the correct repeat count, the second one writes the actual array. – janneb Oct 14 '20 at 14:24
-2
do mi=1, 6
    do ni=1, 6
        write(*,"(ES8.1,$)") real(H(mi,ni))
    end do
    write (*,*) ''
end do
  • 3
    Please [edit] your answer to add details about what this (non-standard) code example does, and why it's better than the standard-compliant alternatives. – francescalus Jan 18 '22 at 13:33
  • 2
    See also https://stackoverflow.com/questions/28724722/decoding-specification-aa-for-write-statement Certainly de not please just dump a piece of code int an answer but tell us what the code does. – Vladimir F Героям слава Jan 18 '22 at 13:39