Input 如何用Fortran从文件中读取数字并立即对每个数字进行计算?
我对Fortran完全不熟悉,我正试图在这里学习这门语言: . 我有一些C和Python的基本经验,但不太多,比如入门类之类的 所以在练习4.1中,他们要求我从文件中输入一些数字,并检查这些数字是偶数还是奇数。以下是输入数字的代码:Input 如何用Fortran从文件中读取数字并立即对每个数字进行计算?,input,fortran,Input,Fortran,我对Fortran完全不熟悉,我正试图在这里学习这门语言: . 我有一些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')
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个数字,我是否必须手动分配每个数字?有没有其他方法可以让我在这样的情况下快速计算质量数?每次读取都会向前移动读取指针。因此,每次新读取时,都会从文件中读入一行 最简单的方法是一直读取,直到
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的数字,它不作为任何其他读/写操作的单位。大量的数字意味着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)。如果模是基本的,那么你可以很容易地做到。。。模是基本的,所以你很幸运(这很常见)
有一个看起来不错的。使用基本功能可以进一步增强这些功能。
这应该给你足够的时间来解决这个问题
或者您可以读取文件以查找大小,关闭并重新打开它,然后分配X、Y、Z和奇数。。。我给出的例子更像是流媒体的例子。人们通常应该使用DO-WHILE而不是GOTO,但从概念上讲,启动GOTO可能更容易。(您需要一个出口或一些DO WHILE(IOSTAT/=)才能中断)打开文件后,循环查看您要读取的行数。要么每次读取时覆盖变量并直接在循环中进行计算,要么将数字存储在数组中并稍后在数组上循环。取决于你以后是否需要这些变量。我们通常不会在问题中发布最终代码。这个问题通常只包含你的问题。哦,好吧,我想我会删除它。这是什么,固定格式f77/f90混合:/arrgghh,它灼伤了我的眼睛。。。请特别注意,当
x
是一个数组时,赋值左侧的x(:)
与x
有细微的不同。如果你对细微的差别不完全满意,最好使用x
来表示整个数组。这不是现代的fortran,我不建议使用GOTO。它使代码难以阅读,并且在20多年前就变得不必要了。正如高绩效分数所指出的,对于像我这样的初学者来说,这看起来很难,但总有一天我会努力理解这一点。谢谢你的帮助这是Fortran 08,对吗?我不能使用newunit功能,因为我使用的是FTN95。还有别的办法吗?你说得对-newunit
是最近添加的。如果这不可用,您可以将iounit
设置为一个您确信安全的数字,例如100几乎总是可以的。然后使用unit=
打开文件,而不是使用newunit=
。如果要保存数据,可以读取两次。第一次用一个计数器就变成了一些垃圾变量。然后在此基础上分配存储变量。第二次读取,倒带iounit,然后将存储变量从1填充到计数器。@mark-s几乎总有一种比从文件中两次读取相同数据更好的方法。这里有一些关于如何扩展阵列的想法:好吧,这与问题无关,但这里有一个简短的注释回答:与内存相比,文件I/O速度较慢。因此,读取数据两次通常不是一个好主意。但这意味着您在开始读取之前不知道阵列需要有多大,这反过来意味着您可能需要动态地增长阵列。关于该问题的公认答案中的第二个示例显示了一种很好的方法,即使用move\u alloc
,如果您发现需要一个更大的数组,而该数组已经部分填充。