如何从Fortran中的文件中读取数字并立即对每个数字进行计算?

时间:2016-10-11 11:46:53

标签: input fortran

我对Fortran完全陌生,我试图在这里学习这门语言: http://www.fortrantutorial.com/files-precision/index.php。我有一些C和Python的基本经验,但并不多,比如介绍类等。

因此在练习4.1中,他们要求我从文件中输入一些数字,并检查这些数字是偶数还是奇数。以下是输入数字的代码:

    program readdata
    implicit none
    !reads data from a file called mydata.txt
    real :: x,y,z
    open(10,file='mydata.txt')
            read(10,*) x,y,z
    print *,x,y,z
    end program  readdata

文件mydata.txt包含一些随机数。他们可以通过以下方式检查数字是偶数还是奇数:

   if (mod(num,2)>0) then……

我的问题是:如果这个文件有10个或1000个数字,我是否必须手动分配它们中的每一个?有没有其他方法让我用这样的质量数字快速计算呢?

2 个答案:

答案 0 :(得分:4)

每次读取也会向前移动读指针。因此,对于每次新读取,都会从文件中读入新行。

最简单的方法是继续阅读,直到READ语句返回错误。当然,您必须传递READ的变量才能将其错误写入。像这样:

program readdata
    implicit none
    real :: x, y, z
    integer :: iounit, ios
    open(newunit=iounit, file='mydata.txt', iostat=ios, action='READ')
    if (ios /= 0) STOP 1
    do
        read(iounit, *, iostat=ios) x, y, z
        if (ios /= 0) exit
        print *, x, y, z
    end do
    close(iounit)
end program readdata

更新:如果您仅限于Fortran 95,正如OP在其评论中所建议的那样,这里有什么要改变:而不是

integer :: iounit, ios
open(newunit=iounit, ...)

你使用

integer :: ios
integer, paramter :: iounit = 100
open(unit=iounit, ...)

所有重要的是iounit是一个大于10的数字,不用作任何其他读/写操作的单位。

答案 1 :(得分:-3)

一定数量的数字意味着X,Y和Z需要超过每个数字的单个数字...所以这样的事情应该让你向解决方案传递:

    program readdata
    implicit none
    !reads data from a file called mydata.txt
    INTEGER, PARAMETER              :: max2process = 10000
    INTEGER                         :: I
    INTEGER                         :: K = 0
    real   , DIMENSION(max2process) :: x,y,z
    LOGICAL, DIMENSION(max2process) :: ODD = .FALSE.
    open(10,file='mydata.txt')
    10  CONTINUE
    X(:) = 0
    Y(:) = 0
    K(:) = 0
    DO I = 1, max2process
      K = K + I
      read(10,*, EOF=99) x(I), y(I), z(I)
      print *,x(I), y(I), z(I)
    ENDDO
    WRITE(*,22) I, MINVAL(X(1:I)), MAXVAL(X(1:I)
22  FORMAT(' MIN(X(1:',I5,')=',0PE12.5,'  Max=',0PE12.5)
    odd = .FALSE.
    WHERE (MODULO(X, 2) /= 0)
      ODD = .TRUE.
    ENDWHERE
    DO I = 1, 10
      WRITE(*,88) I, X(I), odd(I)
88    FORMAT('x(', I2,')=',0PE12.5,' odd="',L1,'"')
    EBDDO
    WRITE(*,*) ' we did not hit the end of file... Go back and read some more'
    GOTO 10

99  WRITE(*,*) 'END of file reached at ', (K-1)
    end program  readdata

基本上是这样的,但我可能有一个拼写错误(LTR)。如果MODULO是ELEMENTAL,那么你可以轻松地做到......而且MODULO是ELEMENTAL,所以你很幸运(这很常见)。

https://rosettacode.org/wiki.Even_or_Odd#Fortran看起来不错。使用ELEMENTAL FUNCTION可以进一步增强功能。 这应该足以让你解决这个问题。

或者您可以读取文件以查找大小,关闭并重新打开它,然后分配X,Y,Z和Odd ......我给出的示例更像是一个流式示例。一般应该使用DO WHILE而不是GOTO,但是从概念上开始GOTO可以更容易。 (你需要一个EXIT或一些DO WHILE(IOSTAT / =)才能爆发)