我正在编写一个代码来读取巨大的文件(文件XYZ),它有几个对象(比如A,B,C,D,E ......可能会有更多,每个对象有数百个数据文件)。现在我需要将文件读入Fortran并选择一个对象,例如'对象B',并将'对象B'的所有信息写入我使用fortran代码创建的新文件中。
每个对象(来自A -....)具有由头文件和数据数组组成的信息(矩阵(i,j),其中i对于每个文件而变化,并且j = 4)。我必须将头文件和数组数据都读入新文件中,并且这些对象(A -....)不是按顺序排序的(假设在A之后可能是C或D)。
我编写了一个小代码,但它似乎不能正常工作,因为我要么只能输出标题而不能输出数组,要么根本没有附加对象和代码的数据文件。
program trail
implicit none
CHARACTER (LEN=5) :: thumb='3C286', SOURCE
INTEGER :: pair(4), n,io, allocstat
real, dimension(:,:),allocatable:: a
CHARACTER (LEN=20) :: POLCODE, DEC, RA
CHARACTER (LEN=40) :: TELESCOPE, NAME_MY, DATA_FILENAME, object , date, TEXT, HEADER, restfreq,BANDWIDT, TSYS, OBSTIME, ANGLE
character(len=180) :: Outdat
character(len=75) :: ra_1, residu, flux, vlafit
open(2, FILE='trail9.txt',POSITION='APPEND')
do
open(1, File="column_3C286_iteration1.txt",status='old' )
read(1,*), SOURCE
10 if(Source.eq.'OJ287') then
! READING THE DATA
read(1,'(A40)') DATA_FILENAME
read(1,'(A40)') TELESCOPE
read(1,'(A40)') NAME_MY
read(1,'(A40)') data_filename
read(1,'(A40)') OBJECT
read(1,'(A40)') restfreq
read(1,'(A20)') polcode
read(1,'(A40)') angle
read(1,'(A40)') date
read(1,'(A40)') bandwidt
read(1,'(A40)') tsys
read(1,'(A40)') obstime
read(1,'(A20)') ra
read(1,'(A20)') dec
read(1,'(A40)') text
read(1,'(A40)') header
read(1,'(A180)') OUTDAT
read(1,"(T2, A3,T30,A4, T50,A6,T67,A6)"),ra_1, residu, flux, vlafit
n=0
do
read(1,*,iostat=io) pair
if (io/=0) exit
n = n + 1
end do
allocate(a(n,4),stat=allocstat)
do i=1,n
read(1,*) (a(i,j),j=1,4 )
enddo
if (index(data_filename,'#')>0 ) then
!WRITING THE DATA
write(2,'(A40)') DATA_FILENAME
write(2,'(A40)') TELESCOPE
write(2,'(A40)') NAME_MY
write(2,'(A40)') data_filename
write(2,'(A40)') OBJECT
write(2,'(A40)') restfreq
write(2,'(A20)') polcode
write(2,'(A40)') angle
write(2,'(A40)') date
write(2,'(A40)') bandwidt
write(2,'(A40)') tsys
write(2,'(A40)') obstime
write(2,'(A20)') ra
write(2,'(A20)') dec
write(2,'(A40)') text
write(2,'(A40)') header
WRITE(2,'(A180)') OUTDAT
Write(2,"(T2, A3,T30,A4, T50,A6,T67,A6)"),ra_1, residu, flux, vlafit
do i=1,n
write(2,"(T1,F10.4: T27,F10.4,T47, F10.4, T63,F10.4, T75,F10.4 )"), (a(i,j), j=1,4)
end do
end do
end if
end do
end program trail
答案 0 :(得分:1)
请尝试将pair
的类型从整数更改为实数,并将代码修改为
real :: pair(4)
integer :: i
n = 0
do
read(1,*,iostat=io) pair
if (io/=0) exit
n = n + 1
end do
do i = 1, n + 1
backspace( 1 )
enddo
这样,read语句对包含四个浮点数的行进行计数,并在行中找到非数字字符(如#)时停止读取。请注意backspace()
执行n + 1次,以便文件指针返回当前数据部分的顶部。
虽然不是很确定,但我也认为以下公开声明
open(1, File="column_3C286_iteration1.txt",status='old' )
如果这对应于数据文件,则应在最外面的DO循环之前写入。
总结一下,我建议进行以下修改:
real :: pair(4)
integer :: i
open(1, File="column_3C286_iteration1.txt",status='old' )
do
read(1,*,end=5000), SOURCE
if( Source .eq.'OJ287' ) then
! read the remaining header and data lines in one block.
read(1,'(A40)') DATA_FILENAME
read(1,'(A40)') TELESCOPE
...
read(1,"(T2, A3,T30,A4, T50,A6,T67,A6)"),ra_1, residu, flux, vlafit
n = 0
do
read(1,*,iostat=io) pair
if (io/=0) exit
n = n + 1
end do
do i = 1, n + 1
backspace( 1 )
enddo
if ( allocated( a ) ) deallocate( a )
allocate( a( n, 4 ) )
do i = 1, n
read( 1, * ) a( i, 1:4 )
enddo
!! write out the obtained data to file 2.
endif
enddo
5000 continue
修改强>
如果我们只想复制一个"标题+数据"对于不同的文件,更简单地回显块中的所有行而不进行格式化。例如,程序可能如下所示。
character(200) :: str, field
integer :: ios
real :: dum
open( 10, file="input.dat", status="old" )
do
read( 10, "(a)", end=5000 ) str
if ( trim(str) == "OJ287" ) then !! search for the target block
print "(a)", trim(str) !! print the tag
!! read one block.
do
read( 10, "(a)", end=5000 ) str
read( str, * ) field !! get the first field of a line
if ( field(1:1) == "#" .or. field(1:2) == "ra" ) then
print "(a)", trim(str) !! header part
else
read( str, *, iostat=ios ) dum !! test if this line starts with a number
if ( ios == 0 ) then
print "(a)", trim(str) !! data part
else
backspace( 10 )
exit
endif
endif
enddo
endif
enddo
5000 continue