Fortran:如何从文本文件的每一行读取第一个字符?

时间:2009-11-01 23:39:53

标签: file-io fortran

这是我第一次尝试在Fortran中编程。我正在尝试编写一个打印Fibonacci sequence的前1476个术语的程序,然后检查每个术语的第一个数字并存储发生在一个中的1s,2s,3s,...,9s的数量。阵列。

我似乎无法弄清楚的问题是如何读取每个术语的第一个数字。我已经尝试了几件事,但我对Fortran技术的知识有限。我将这些术语写入文本文件,其目的是读取每行的第一个数字并在数组中累积相应的数字。有没有人有任何建议如何做到这一点?

到目前为止,这是我的代码:

编辑:我包含了我读取文件的代码。现在它只打印出来3.60772951994415996E-313, 这似乎是某种地址,因为它不是斐波那契数字之一。此外,它是唯一印刷的东西,我预计它会打印出文件的每一行......)

编辑编辑:考虑到这一点后,或许有一种方法可以将文本文件的写入格式化为第一个数字。有没有办法设置实数的有效位数数字为1?:P)

subroutine writeFib(n)
  integer ::  i
  real*8 :: prev, current, newFib
  prev = 0
  current = 1
  do i = 1, n
     newFib = prev + current
     prev = current
     current = newFib
     write(7,*) newFib
  end do
  return
end subroutine

subroutine recordFirstDigits(a)
  integer :: openStat, inputStat
  real*8 :: fibNum
  open(7, file = "fort.7", iostat = openStat)
  if (openStat > 0) stop "*** Cannot open the file ***"
  do
     read(7, *, iostat = inputStat) fibNum
     print *,fibNum
     if (inputStat > 0) stop "*** input error ***"
     if (inputStat < 0) exit ! end of file
  end do
  close(7)
end subroutine

program test
  integer :: k, a(9)
  k = 1476
  call writeFib(k)
  call recordFirstDigits(a)
end program

5 个答案:

答案 0 :(得分:1)

你能用格式(A1)阅读吗?已经20年了,所以我不记得确切的语法。

答案 1 :(得分:1)

我想知道为什么open语句在文件7尚未关闭时成功。我认为在写和读之间需要一个endfile语句和/或一个倒带语句。

保罗·汤姆林(Pau​​l Tomblin)在你首先解决你的阅读工作问题之后发布了你必须做的事情。

答案 2 :(得分:1)

虽然建议已经到位,但也有一些事情被遗忘了。 REAL类型的范围,以及一些格式问题。

无论如何,这是一个已修补的解决方案,已编译并正常工作,因此请尝试查看这是否适合您。我冒昧地选择自己的斐波那契数字计算方法。

  program SO1658805
  implicit none

  integer, parameter :: iwp = selected_real_kind(15,310)
  real(iwp) :: fi, fib
  integer :: i
  character(60) :: line
  character(1) :: digit
  integer :: n0=0, n1=0, n2=0, n3=0, n4=0, n5=0, n6=0, n7=0, n8=0, n9=0

  open(unit=1, file='temp.txt', status='replace')
  rewind(1)
  !-------- calculating fibonacci numbers -------
  fi = (1+5**0.5)/2.
  do i=0,1477
    fib = (fi**i - (1-fi)**i)/5**0.5
    write(1,*)fib,i  
  end do
  !----------------------------------------------
  rewind(1)

  do i=0,1477
    read(1,'(a)')line
    line = adjustl(line)
    write(*,'(a)')line


    read(line,'(a1)')digit

     if(digit.eq.' ') n0=n0+1
     if(digit.eq.'1') n1=n1+1
     if(digit.eq.'2') n2=n2+1
     if(digit.eq.'3') n3=n3+1
     if(digit.eq.'4') n4=n4+1
     if(digit.eq.'5') n5=n5+1
     if(digit.eq.'6') n6=n6+1
     if(digit.eq.'7') n7=n7+1
     if(digit.eq.'8') n8=n8+1
     if(digit.eq.'9') n9=n9+1
  end do
  close(1)

  write(*,'("Total number of different digits")')
  write(*,'("Number of digits 0: ",i5)')n0
  write(*,'("Number of digits 1: ",i5)')n1
  write(*,'("Number of digits 2: ",i5)')n2
  write(*,'("Number of digits 3: ",i5)')n3
  write(*,'("Number of digits 4: ",i5)')n4
  write(*,'("Number of digits 5: ",i5)')n5
  write(*,'("Number of digits 6: ",i5)')n6
  write(*,'("Number of digits 7: ",i5)')n7
  write(*,'("Number of digits 8: ",i5)')n8
  write(*,'("Number of digits 9: ",i5)')n9

  read(*,*)

  end program SO1658805

噢,......我刚刚读到你需要存储在数组中的数字位数。虽然我只计算了它们。

哦,好吧,......“作为读者留下的练习......”: - )

答案 3 :(得分:0)

  

我收到了'行尾'运行时错误

你没有显示! code to read here...,这使得你很难猜出你做错了什么: - )

也许你需要一个循环来读取每一行,然后当没有更多行时跳出循环到一个continue语句。

这样的事情:

   do
      read(7,*,end=10) fibNumber
   end do
   10 continue

更好 - 看看the more modern style used in this revcomp program

答案 4 :(得分:0)

这里有一些提示:

  1. 您不需要使用字符, 这个问题的文件i / o要少得多 (除非你忘了陈述一个 必须创建文件)。
  2. 因此,使用数学来查找统计信息。有许多resources on Fibonacci numbers可能提供简化的洞察力,或者至少是一种独立发现您的答案的方法
    • 以下是非Fortran术语的复杂提示:
      floor(10^(frac(log_10(7214989861293412))))
      (将其放在Wolfram Alpha中查看它的作用。)
    • 一个简单的提示(对于不同的方法)是你可以做的 在Fortran很简单 循环中的算术运算 构造 - 至少在解决方案的第一次通过。
  3. 累计您的统计信息 去即可。这个建议甚至适用于你的角色驱动方法。 (这个问题非常适合 想出一个可爱的索引 您的统计计划,但有些 人们讨厌可爱的计划 节目。如果你不害怕 可爱......然后你可以有联想 Fortran中的数组只要你的 键是整数; - )
  4. 最重要的方面 问题是你将要的数据类型 使用来计算答案。对于 例如,here's the last number you will have to print
  5. 干杯, - 杰拉特