我有一个旧的Fortran程序,用于从文本文件中读取记录。记录的格式如下:
record_type field1 field2 ... fieldN ;
这些记录可能分布在几行,即人物;表明记录已经完成。旧代码是:
2 read(data,"(a130)",end=3)line
shift=adrec(nbrec)-1
read(line,*,end=1)typrec(nbrec),(field(shift+i),i=1,65)
1 do
do j=shift+1,shift+i-1
k=index(field(j),';')
if(k .ne. 0)then
if(k .eq. 1)then
adrec(nbrec+1)=j
else
field(j)(k:)=''
adrec(nbrec+1)=j+1
endif
go to 2
endif
endo
read(data,"(a130)")line
read(line,*,end=1)(field(shift+i),i=1,65)
enddo
3 continue
此代码适用于英特尔编译器(ifort)。随着gfortran它失败了!第一个问题是第三行的隐式读取,使用ifort,使得i等于实际读取的字段数,而在gfortran中它总是给出65.第二个问题是在同一个隐式读取中,使用ifort , 人物 ;被读作普通字段但跳过gfortran。
任何人都可以帮我解决这两个问题吗?任何其他一起替换代码的想法也是受欢迎的。
答案 0 :(得分:1)
这有用吗?除do while
(和exit
控制结构......)之外,这符合f77(我认为)。如果需要,可以相对容易地用goto / continue替换dos。我不知道你最终想要什么类型的字符串,所以我返回字符串(并假设一个字段不能超过24个字符)...我还假设一个“行”不能超过1024字符。
很抱歉没有评论,但我认为功能名称是描述性的。一般来说,我认为在编程时使用函数/子程序是个好主意,因为这样可以使代码更加可读......
program main
character*1024 line
integer stat,stat2,i,nf
character*24 fld
character*16 fmt
open(unit=21,file='test.dat',status='old')
stat=0
do while(stat.eq.0)
call readline(21,line,stat)
stat2=0
i=1
do while(.true.)
call getfield(line,fld,stat2)
if(stat2.ne.0) exit
i=i+1
write(*,*) i,stat2,fld
enddo
write(*,*) " "
enddo
end
subroutine getfield(line,field,stat)
integer l,i,stat
character*(*) line,field
!Get first field and shift the line
l=1
if(line.eq.' ')then
stat=1
else
stat=0
endif
do while (line(l:l).eq.' ')
l=l+1
enddo
i=l
do while (line(i:i).ne.' ')
i=i+1
enddo
if((line(l:l).eq.'"').or.(line(l:l).eq."'"))then
do while(line(i:i).ne.line(l:l))
i=i+1
enddo
endif
field=line(l:i)
line=line(i+1:)
return
end
subroutine readline(unit,line,stat)
integer unit
character*(*) line
integer stat,i
!read one "line" Lines are sequences seperated by ';' (can have newlines in there)
stat=0
i=1
do while (.true.)
read(unit,'(A)',end=100) line(i:)
i=index(line,';')
if(i.eq.0)then
i=len_trim(line)+2
else
line(i:)=' ' !remove the trailing semicolon.
exit
endif
enddo
return
100 continue
stat=1
return
end