我正在尝试在gfortran编译器中编译以下代码:
do_cmd = .not. is_group
do while (.not. EOF(unit=100) .and. .not. flag_stop)
read (100, '(A)', iostat = ios) buf
if (buf(1:1)=="#") then
! comment line
elseif ((buf(1:2)=="v ") .and. do_cmd) then ! vertex
read(buf(2:), *, iostat=ios) p(1), p(2), p(3)
if (ios.ne.0) then
print "(/,2x,'Error of reading vertex position from obj-file (line #'(I3)');')", line_index
stop
end if
但是我在编译代码时遇到了这些错误:
do while (.not. EOF(unit=100) .and. .not. flag_stop)
1
Error: Keyword argument requires explicit interface for procedure ‘eof’ at (1)
和
do while (.not. EOF(unit=100) .and. .not. flag_stop)
1
Error: Function ‘eof’ at (1) has no IMPLICIT type
如果有人能帮助我,我将非常感激。
编辑: 我是fortran的新手,无法了解eof功能在gfortran中是如何工作的。
在参数中使用unit = 100是什么意思? 并且还认为默认情况下它是一个逻辑功能。我该如何隐含其类型?
答案 0 :(得分:1)
据我所知,EOF
不是Fortran标准的一部分。至少我无法在任何地方找到它。
在大多数编程语言中, EOF 代表"文件结束",对我来说很明显,你的例子中的EOF
应该是当且仅当与.TRUE.
关联的读指针(在您的情况下为unit
)指向文件末尾时,返回100
的逻辑函数。
您可以使用ios
变量检查在阅读过程中是否遇到 EOF 。在这种情况下,它将是-1
。然后,您可以使用exit
语句立即退出循环。
如果您不喜欢-1
,并且使用Fortran 2003兼容编译器,您甚至可以使用模块ISO_FORTRAN_ENV
,它提供(除其他外)参数{{ 1}}。
这是一个非常简单的例子:
IOSTAT_END
但需要注意的是:此代码仅作为示例。它只会在遇到 EOF 时退出循环 - 如果program iso
use ISO_FORTRAN_ENV
implicit none
integer, parameter :: u = 100
character(len=80) :: buf
integer :: ios
open(unit=u, action='READ', status='OLD', file='data.dat')
read_loop : do
read(u, '(A)', iostat=ios) buf
if (ios == IOSTAT_END) exit read_loop ! EOF
if (buf(1:1) == '#') cycle read_loop ! This line is a comment
write(*, *) buf
end do read_loop
close(u)
end program iso
因任何其他原因失败,则不会退出循环。 (还有一些其他原因导致读取失败。)如果其他错误持续存在,那么这将导致无限循环。
答案 1 :(得分:0)
尝试用户定义的EOF
函数(如下所示)可能有用,可以最大限度地减少代码修改量;但是因为这个函数效率很低,我想最好重写原始代码,以便直接在iostat
语句中使用read
(如上所述)......
module eofmod !<-- please save this in a separate file, compile, and link with other programs
implicit none
contains
logical function EOF( unit )
integer, optional :: unit
integer :: ios
if ( .not. present( unit ) ) stop "no unit given"
read( unit, *, iostat=ios )
if ( ios == -1 ) then
EOF = .true.
else
EOF = .false. ; backspace( unit )
endif
end function
end module
program test
use eofmod !<-- needs to be inserted at the top of routines (or modules) where "EOF" is used
implicit none
character(200) :: buf
open(10, file="test.dat", status="old")
do while ( .not. EOF( unit=10 ) )
read( 10, "(a)" ) buf
print "(a)", trim( buf )
enddo
close(10)
end program