File io Fortran read()读取最后一行两次?
所以,假设我试图读取一个文件,其长度我之前不知道。我们可以在需要时使用iostat和while循环来中断,但我对此有一个问题。也就是说,我编写的代码读取最后一行两次。我肯定有一个显而易见的解决办法,但我似乎无法找到答案。我并不完全理解read()或iostat函数是如何工作的(我对fortran非常陌生),但我无法从文档中收集到太多信息,所以我希望这里的人能提供帮助 以下是我编写的(相关)代码:File io Fortran read()读取最后一行两次?,file-io,fortran,File Io,Fortran,所以,假设我试图读取一个文件,其长度我之前不知道。我们可以在需要时使用iostat和while循环来中断,但我对此有一个问题。也就是说,我编写的代码读取最后一行两次。我肯定有一个显而易见的解决办法,但我似乎无法找到答案。我并不完全理解read()或iostat函数是如何工作的(我对fortran非常陌生),但我无法从文档中收集到太多信息,所以我希望这里的人能提供帮助 以下是我编写的(相关)代码: filename = 'test.txt' iostat_1 = 0 iostat_2 = 0
filename = 'test.txt'
iostat_1 = 0
iostat_2 = 0
open(newunit = lun, file = filename, status = 'old', iostat = iostat_1)
if (iostat_1 == 0) then
do while(iostat_2 == 0)
if(iostat_2 == 0) then
read(lun,*,iostat = iostat_2) dum, real_1,real_2,int_1
print *, dum, real_1,real_2,int_1
endif
enddo
endif
假设我的输入文件是
1 1.0 1.0 1
2 2.0 2.0 1
3 3.0 3.0 1
4 4.0 4.0 4
然后,从print语句到终端的输出将是
1 1.0 1.0 1
2 2.0 2.0 1
3 3.0 3.0 1
4 4.0 4.0 4
4 4.0 4.0 4
因此,请记住以下几点:这里的主要目的是能够读取具有任意行数的文件。我对先读取行数的解决方案不感兴趣
谢谢你的帮助
更新好的,我刚刚解决了问题。话虽如此,我想知道是否有一个解决方案比我的更简单。以下是我为解决此问题所做的工作
! Body of ReInsert
filename = 'rpriov3.dat'
iostat_1 = 0
iostat_2 = 0
open(newunit = lun, file = filename, status = 'old', iostat = iostat_1)
if (iostat_1 == 0) then
do while(iostat_2 == 0)
if(iostat_2 == 0) then
read(lun,*,iostat = iostat_2) dum, real_1,real_2,int_1
if(iostat_2 == 0) then !<---- Added this nested if statement
print *, dum, real_1,real_2,int_1
endif
print *, iostat_2
endif
enddo
endif
!复插体
文件名='rpriov3.dat'
iostat_1=0
iostat_2=0
打开(newunit=lun,file=filename,status='old',iostat=iostat_1)
如果(iostat_1==0),则
do while(iostat_2==0)
如果(iostat_2==0),则
读取(lun,*,iostat=iostat_2)dum,实值_1,实值_2,int_1
如果(iostat_2==0),那么 正如您所发现的,当您设置iostat
参数时,read
命令不会覆盖它要求的变量
正如您已经注意到的,您的解决方案有些复杂
首先:
do while (condition)
if (condition) then
...
end if
end do
在这种情况下,内部if
语句是完全剩余的。除非condition
为true,否则循环不会运行,因此除非condition
本身的计算不会更改结果1),否则将始终执行if
子句
我要看的第二件事是:如果打开失败,会发生什么?在大多数情况下,我希望打印错误并退出:
open(..., iostat=ios)
if (ios /= 0) then
print*, "Error opening file"
STOP 1
end if
do while (...)
...
end do
即使您不想在打开
中出现错误时退出程序,通常也有方法使代码比永久嵌套更具可读性。例如,您可以一次又一次(在自己的循环中)要求用户输入文件名,直到文件打开或用户输入退出消息
ios = 1
do while (ios /= 0)
write(*, *, advance='no') "Enter filename (or 'quit') :"
read(*, *) filename
if ( trim(filename) == "quit" ) STOP
open(newunit=lun, file=filename, ..., iostat=ios)
end do
最后是最内部的if
块。由于在出现错误时仍希望退出循环,因此可以在循环中使用exit
语句立即退出循环,而无需执行循环块的其余部分:
do
read(..., iostat=ios) ...
if (ios /= 0) exit
print *, ....
end do
这是一个无限循环,一旦遇到读取错误(通常,但不一定是EOF),就会显式退出。由于print
语句位于exit
之后,因此在出现此类错误时不会执行该语句
1) 我的意思是类似于这个C代码段I++<10
,它对I
进行测试,并对10
进行递增