Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/fortran/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
File io Fortran read()读取最后一行两次?_File Io_Fortran - Fatal编程技术网

File io Fortran read()读取最后一行两次?

File io Fortran read()读取最后一行两次?,file-io,fortran,File Io,Fortran,所以,假设我试图读取一个文件,其长度我之前不知道。我们可以在需要时使用iostat和while循环来中断,但我对此有一个问题。也就是说,我编写的代码读取最后一行两次。我肯定有一个显而易见的解决办法,但我似乎无法找到答案。我并不完全理解read()或iostat函数是如何工作的(我对fortran非常陌生),但我无法从文档中收集到太多信息,所以我希望这里的人能提供帮助 以下是我编写的(相关)代码: filename = 'test.txt' iostat_1 = 0 iostat_2 = 0

所以,假设我试图读取一个文件,其长度我之前不知道。我们可以在需要时使用iostat和while循环来中断,但我对此有一个问题。也就是说,我编写的代码读取最后一行两次。我肯定有一个显而易见的解决办法,但我似乎无法找到答案。我并不完全理解read()或iostat函数是如何工作的(我对fortran非常陌生),但我无法从文档中收集到太多信息,所以我希望这里的人能提供帮助

以下是我编写的(相关)代码:

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
进行递增