I need to write some data to file in Fortran 90. How should I use WRITE (*,*) input
to have the values grouped in columns? WRITE
always puts a new line
after each call, that's the problem.
code example:
open (unit = 4, file = 'generated_trajectories1.dat', form='formatted')
do time_nr=0, N
write (4,*) dble(time_nr)*dt, initial_traj(time_nr)
end do
And now the point is to have it written in separate columns.
You can use implied DO loops to write values as single records. Compare the following two examples:
integer :: i
do i=1,10
write(*,'(2I4)') i, 2*i
end do
It produces:
1 2
2 4
3 6
...
Using implied DO loops it can rewritten as:
integer :: i
write(*, '(10(2I4))') (i, 2*i, i=1,10)
This one produces:
1 2 2 4 3 6 ...
If the number of elements is not fixed at compile time, you can either use the <n>
extension (not supported by gfortran
):
write(*, '(<n>(2I4))') (i, 2*i, i=1,n)
It takes the number of repetitions of the (2I4)
edit descriptor from the value of the variable n
. In GNU Fortran you can first create the appropriate edit descriptor using internal files:
character(len=20) :: myfmt
write(myfmt, '("(",I0,"(2I4))")') n
write(*, fmt=myfmt) (i, 2*i, i=1,n)
Of course, it also works with list directed output (that is output with format of *
):
write(*, *) (i, 2*i, i=1,10)
This really depends on what data you are trying to write to file (i.e. whether you have a scalar within a loop or an array...). Can you include a description of this in your question?
If your are trying to write a scalar multiple times to the same row then try using non-advancing I/O, passing the keyword argument advance="no"
to the write statement, e.g.
integer :: x
do x = 1,10
write(*, fmt='(i4,1x)', advance="no") x
end do
However, be aware of a suprise with non-advancing I/O.
The answer depends on your answer to Chris's question. If you want a single line, then you will have to use non-advancing IO as described by Chris. Without this, with multiple formatted write statement you will always get multiple lines.
Also, you will likely need to use formatted IO instead of list-directed (*) IO. The rules are loose for list-directed IO. Different compilers may produce different output. With many output items, line breaks are likely to keep the output lines from being too long.
Here a format that should work if all of your variables are reals:
write (4, '( *(2X, ES14.6) )', advance="no" )
how about the good old $ edit descriptor:
write(*, fmt='(i4,$)') x
remember to do a write(*,*) after your loop...