Reputation: 2592
In a Fortran program, I need to write an array into a file with a specific format. I perfectly works for smaller array (e.g. alen=10 in the example below), but won't work for bigger arrays: it then splits each line into two, as if a maximum number of characters per line was exceeded.
Example (very similar to the structure in my program):
PROGRAM output_probl
IMPLICIT NONE
INTEGER, PARAMETER :: alen=110
DOUBLE PRECISION, DIMENSION(alen)::a
INTEGER :: i,j
OPEN(20,file='output.dat')
30 format(I5,1x,110(e14.6e3,1x))
DO i=1,15
DO j=1,alen
a(j)=(i*j**2)*0.0123456789
ENDDO
write(20,30)i,(a(j),j=1,alen)
ENDDO
END PROGRAM output_probl
It compiles and runs properly (with Compaq Visual Fortran). Just the output file is wrong. If I for example change the field width per array item from 14 to 8, it'll work fine (this is of course not a satisfactory solution). I thought about an unsuitable default maximum record length, but can't find how to change it (even with RECL which doesn't seem to work - if you think it should, a concrete example with RECL is welcome).
This might be basic, but I've been stuck with it for some time... Any help is welcome, thanks a lot!
Upvotes: 0
Views: 2782
Reputation: 59
The program below should test. With Absoft compiler it works fine for n=10000, 10 character words, that is a line 100000 characters wide (plus a couple) in all. With G95 I get a message "Not enough storage is available to process this command" for n=5000 (n=4000 works). character*10,dimension(:),allocatable:: test integer,dimension(:),allocatable::itest
1 write(,)'Enter n > 0' read , n if(n.le.0) then write(,)'requires value n > 0' go to 1 endif write(,*)'n=',n allocate(test(n),itest(n))
write(test,'((i10))')(i,i=1,n)
write(*,*)test
open(10,file='test.txt')
write(10,*)test
write(*,*)'file test.txt written'
close(10)
open(11,file='test.txt')
read(11,*)itest
write(*,*)itest
end
Upvotes: 0
Reputation: 60008
Why not stream access? With sequential there is allways some processor dependent record length limit.
PROGRAM output_probl
IMPLICIT NONE
INTEGER, PARAMETER :: alen=110
DOUBLE PRECISION, DIMENSION(alen)::a
INTEGER :: i,j
OPEN(20,file='output.dat',access='stream', form='formatted',status='replace')
30 format(I5,1x,110(e14.6e3,1x))
DO i=1,15
DO j=1,alen
a(j)=(i*j**2)*0.0123456789
ENDDO
write(20,30)i,(a(j),j=1,alen)
ENDDO
END PROGRAM output_probl
As a note, I would use a character variable for the format string, or place it directly in the write statement, instead of the FORMAT
statement with a label.
Fortran 95 version:
PROGRAM output_probl
IMPLICIT NONE
INTEGER, PARAMETER :: alen=110
DOUBLE PRECISION, DIMENSION(alen)::a
INTEGER :: i,j,rl
character(2000) :: ch
inquire(iolength=rl) ch
OPEN(20,file='output.dat',access='direct', form='unformatted',status='replace',recl=rl)
30 format(I5,1x,110(e14.6e3,1x))
DO i=1,15
DO j=1,alen
a(j)=(i*j**2)*0.0123456789
ENDDO
write(ch,30)i,(a(j),j=1,alen)
ch(2000:2000) = achar(10)
write(20,rec=i) ch
ENDDO
END PROGRAM output_probl
Upvotes: 3