在Fortran中,如何从文件中随机计数白色分隔的值



如果有一个文件包含,例如:

1 2 3   4    5
6  7  8  9  10
   11    12   13
14 15
16             17
        18
  19  20

如何通过在Fortran中对文件中的整数进行计数来获得正确数量的整数(在给定的示例中为20)?

下面是我为这个问题编写的一个小程序。我对它进行了一系列的测试。应该很清楚程序和子例程在做什么,但如果你想解释发生了什么,请询问。如果发现任何错误,请进行修复。

PROGRAM test
  USE iso_fortran_env
  IMPLICIT NONE
  INTEGER :: cnt, filstat
  CHARACTER(len=132) :: aline  ! change the length if you want to
  cnt = 0
  OPEN(101,file='data.txt')
  DO 
     READ(101,'(a132)',iostat=filstat) aline
     IF (filstat/=0) EXIT
     CALL get_int(cnt,aline)
  END DO
  WRITE(*,*) 'counted ', cnt, 'integers'
  CLOSE(101)
CONTAINS
  RECURSIVE SUBROUTINE get_int(cnt, str)
    INTEGER, INTENT(inout) :: cnt
    CHARACTER(*), INTENT(in) :: str
    ! Local variables
    CHARACTER(len= 10), PARAMETER :: digits = '0123456789'
    INTEGER :: d1, os, n
    ! First strip off any leading spaces
    d1 = SCAN(str,digits)
    IF (d1==0) THEN ! no digit was found
       RETURN
    END IF
    ! Read the first integer on the line
    READ(str(d1:),*) n
    cnt = cnt+1
    ! Figure out how many character positions to skip over
    os = INT(LOG10(REAL(n)))+1
    ! Recurse
    CALL get_int(cnt,str(d1+os+1:))
  END SUBROUTINE get_int
END PROGRAM TEST

有趣的问题。

通常情况下,你应该先告诉我们到目前为止你已经尝试了什么。但无论如何。

我提出的一个解决方案是创建一个明显更大的数组,将所有数组设置为无效值,然后从文件中读取。

请确保捕获了iostat参数,否则程序将崩溃。

然后,通过查看该值的第一次出现,您可以推断出大小(并且您已经有了值):

program read_data
    implicit none
    integer, dimension(100) :: d
    integer :: s, err
    d = -9999
    open(unit=100, file='data.txt', action='READ', status='OLD')
    read(100, *, iostat=err) d
    s = 0
    do
        s = s + 1
        if ((s == size(d)) .or. (d(s+1) == -9999)) exit
    end do
    if (s == size(d)) then
         print *, "We might have missed some..."
    end if
    write(*, '(5I5)') d(1:s)
    close(100)
end program read_data

现在这不是一个很好的程序。你在浪费内存(大数组),为了扩大规模,你必须更改代码并重新编译。

我稍后再考虑。

最新更新