我正在尝试编译以下在fortran中编写的代码,但有很多错误

时间:2015-12-03 18:57:43

标签: fortran gfortran

我正在尝试在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是什么意思? 并且还认为默认情况下它是一个逻辑功能。我该如何隐含其类型?

2 个答案:

答案 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