Fortran中重复读取文件同一行的报错问题及修复咨询
解决Fortran重复读取同一行数据时的"End of Record"报错问题
你的问题出在对advance='no'的理解和使用上:当你用read(ut, '(a)', advance='no')读取时,第一次就把文件里那一行的所有字符都读进了lnumber,此时文件指针已经停在该行的末尾。后续循环再执行读取操作时,当前记录(也就是这一行)已经没有剩余字符可以读取,所以触发了"End of record"的运行时错误。
下面给你几种针对性的修复方案,根据你的实际需求选择:
方案1:缓存行内容(推荐,效率更高)
先把整行内容一次性读取到变量中缓存起来,之后直接循环使用这个变量即可,不需要反复操作文件:
program advance implicit none integer , parameter :: ut = 20 character(len=7) :: fname = 'dat.dat' integer :: n, idx character(len=100) :: lnumber open(unit = ut, file =fname, status='old', action='read') ! 一次性读取整行到缓存变量 read(ut, '(a)') lnumber close(ut) ! 读完文件就可以关闭,避免资源占用 n = 10 do idx = 1, n print *, lnumber end do end program advance
方案2:每次循环重置文件指针
如果你需要保持文件打开状态,可以在每次读取前用rewind命令把文件指针重置到文件开头(因为你的文件只有一行,重置开头就相当于回到该行起始位置):
program advance implicit none integer , parameter :: ut = 20 character(len=7) :: fname = 'dat.dat' integer :: n, idx character(len=100) :: lnumber open(unit = ut, file =fname, status='old', action='read') n = 10 do idx = 1, n rewind(ut) ! 重置指针到文件开头 read(ut, '(a)') lnumber print *, lnumber end do close(ut) end program advance
方案3:直接读取数值(如果你的目标是处理实数值)
既然你的文件里是实数值,没必要读取字符串,直接读取到数值变量里再循环使用会更简洁:
program advance implicit none integer , parameter :: ut = 20 character(len=7) :: fname = 'dat.dat' integer :: n, idx real(kind=8) :: val ! 用双精度类型存储长精度的实数值 open(unit = ut, file =fname, status='old', action='read') read(ut, *) val ! 直接读取数值 close(ut) n = 10 do idx = 1, n print *, val end do end program advance
总结一下:advance='no'的作用是读取后不切换到下一个记录,但它不会自动重置当前记录的指针,也不会重复读取已经读完的内容。所以要么提前缓存内容,要么手动重置指针,才是正确的重复读取方式。
内容的提问来源于stack exchange,提问作者Many
相关产品推荐
相关产品推荐

