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

发布于 2024-08-09 04:00:45 字数 1316 浏览 4 评论 0原文

这是我第一次尝试用 Fortran 编程。我正在尝试编写一个程序,打印 斐波那契数列 的前 1476 项,然后检查每一项的第一个数字并存储数组中出现的 1、2、3、...、9 的数量。

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

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

编辑:我包含了用于读取文件的代码。现在它只打印出 3.60772951994415996E-313, 这看起来像是某种地址,因为它不是斐波那契数列之一。另外,它是唯一打印的内容,我希望它会打印出文件的每一行...)

编辑编辑:考虑到这一点后,也许有一种方法可以将写入格式设置为有没有办法将实数的有效位数设置为 1?

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

this is my first time trying to program in Fortran. I'm trying to write a program that prints the first 1476 terms of the Fibonacci sequence, then examines the first digit of each term and stores the number of 1s, 2s, 3s, ..., 9s that occur in an array.

The problem that I can't seem to figure out is how to read the first digit of each term. I've tried several things but am having difficulty with my limited knowledge of Fortran techniques. I write the terms to a text file and the idea is to read the first digit of each line and accumulate the respective number in the array. Does anyone have any suggestions of how to do this?

Here is my code so far:

(edit: I included the code I have for reading the file. Right now it just prints out 3.60772951994415996E-313,
which seems like an address of some sort, because it's not one of the Fibonacci numbers. Also, it is the only thing printed, I expected that it would print out every line of the file...)

(edit edit: After considering this, perhaps there's a way to format the writing to the text file to just the first digit. Is there a way to set the number of significant digits of a real number to one? :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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

梦中楼上月下 2024-08-16 04:00:45

虽然建议已经到位,但也有一些被遗忘的事情。 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

噢,...我刚刚读到您需要将位数存储到数组中。虽然我只是数了一下。

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

Although the suggestions were in place, there were also several things that were forgotten. Range of the REAL kind, and some formatting problems.

Anyways, here's one patched up solution, compiled and working, so try to see if this will work for you. I've took the liberty of choosing my own method for fibonacci numbers calculation.

  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

Aw, ... I just read you need the number of digits stored in to an array. While I just counted them.

Oh well, ... "left as an exercise for the reader ..." :-)

在梵高的星空下 2024-08-16 04:00:45

你能用 FORMAT(A1) 阅读吗? 20 年过去了,我已经不记得具体的语法了。

Can you read with a FORMAT(A1)? It's been 20 years so I don't remember the exact syntax.

温暖的光 2024-08-16 04:00:45

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

Paul Tomblin 发布了在解决了让读取工作的问题之后您必须做的事情。

I wonder why the open statement succeeds when file 7 hasn't been closed. I think you need an endfile statement and/or a rewind statement in between writing and reading.

Paul Tomblin posted what you have to do after you solve your problem in getting reads to work in the first place.

何以笙箫默 2024-08-16 04:00:45

我收到“行尾”运行时错误

您没有显示 !代码在这里阅读... 这使得很难猜测你做错了什么:-)

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

像这样的东西:

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

更好 - 看看 此 revcomp 计划中使用的更现代的风格

I am getting an 'end of line' runtime error

You don't show the ! code to read here... which makes it kind of difficult to guess what you are doing wrong :-)

Perhaps you need a loop to read each line and then jump out of the loop to a continue statement when there are no more lines.

Something like this:

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

Better still - look at the more modern style used in this revcomp program.

对你而言 2024-08-16 04:00:45

这里有一些提示:

  1. 您不需要使用字符
    这个问题的文件 I/O 少得多
    (除非你忘记声明
    必须创建文件)。
  2. 因此,使用数学来查找统计数据。有很多有关斐波那契数列的资源,它们可能提供简化的见解,或者至少提供一种方法独立抽查您的答案。
    • 以下是非 Fortran 术语的复杂提示:

      地板(10^(frac(log_10(7214989861293412))))
      (将其放入 Wolfram Alpha 中看看它的作用。)
    • 一个更简单的提示(对于不同的方法)是你可以做很多
      Fortran 语言很简单
      循环内的算术
      构造——至少是解决方案的第一遍。
  3. 累积您的统计数据
    去吧。这个建议甚至适用于你的性格驱动方法。 (这个问题非常适合
    提出了一个可爱的索引
    计划为您的统计数据,但有些
    人们讨厌可爱的计划
    编程。如果你不害怕
    可爱……那么你就可以有联想
    Fortran 中的数组只要你
    键是整数;-)
  4. 最重要的方面
    问题是你将要使用的数据类型
    使用
    来计算你的答案。为了
    例如, 这是您输入的最后一个数字
    必须打印

干杯,--贾里德

here are some hints:

  1. You don't need to use characters,
    much less file i/o for this problem
    (unless you forgot to state that a
    file must be created).
  2. Therefore, use math to find your statistics. There are lots of resources on Fibonacci numbers that might provide a simplifying insight or at least a way to independently spot check your answers.
    • Here is a complicated hint in non-Fortran lingo:

      floor(10^(frac(log_10(7214989861293412))))
      (Put this in Wolfram Alpha to see what it does.)
    • A simpler hint (for a different approach) is that you can do very
      well in Fortran with simple
      arithmetic inside of looping
      constructs--at least for a first pass at the solution.
  3. Accumulate your statistics as you
    go
    . This advice would even apply to your character-driven approach. (This problem is ideally suited
    for coming up with a cute indexing
    scheme for your statistics, but some
    people hate cute schemes in
    programming. If you don't fear
    cuteness ... then you can have associative
    arrays in Fortran as long as your
    keys are integers ;-)
  4. The most important aspect of this
    problem is the data type you will
    use
    to calculate your answers. For
    example, here's the last number you
    will have to print
    .

Cheers, --Jared

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文