ztl
ztl

Reputation: 2592

Fortran: output large array - exceeded length, split on two lines

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

Answers (2)

user3772612
user3772612

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

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

Related Questions