Фортран: Как мне прочитать первый символ из каждой строки текстового файла? - PullRequest
0 голосов
/ 02 ноября 2009

Я впервые пытаюсь программировать на Фортране. Я пытаюсь написать программу, которая печатает первые 1476 слагаемых последовательности последовательности Фибоначчи , затем проверяет первую цифру каждого слагаемого и сохраняет число 1, 2, 3, ..., 9, которые встречаются в массиве.

Проблема, которую я не могу понять, состоит в том, как прочитать первую цифру каждого термина. Я пробовал несколько вещей, но у меня возникли трудности с моими ограниченными знаниями техники Фортрана. Я записываю термины в текстовый файл, и идея состоит в том, чтобы прочитать первую цифру каждой строки и накапливать соответствующее число в массиве. У кого-нибудь есть предложения, как это сделать?

Вот мой код:

( edit : я включил код, который у меня есть для чтения файла. Сейчас он просто печатает 3.60772951994415996E-313, который выглядит как какой-то адрес, потому что это не одно из чисел Фибоначчи. Кроме того, это единственное напечатанное, я ожидал, что оно напечатает каждую строку файла ...)

( edit edit : Возможно, после этого есть способ отформатировать запись в текстовый файл только в первую цифру. Есть ли способ установить количество значащих цифр действительного числа одному?: 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 ]

1 голос
/ 02 ноября 2009

Несмотря на то, что предложения были на месте, было также несколько вещей, которые были забыты. Диапазон реального типа и некоторые проблемы с форматированием.

В любом случае, вот одно исправленное решение, скомпилированное и работающее, поэтому попробуйте посмотреть, сработает ли оно для вас. Я позволил себе выбрать собственный метод вычисления чисел Фибоначчи.

  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

Оу ... Я только что прочитал, что вам нужно количество цифр, хранящихся в массиве. Пока я их только посчитал.

Ну да ладно ... "оставлено как упражнение для читателя ...": -)

1 голос
/ 02 ноября 2009

Интересно, почему оператор open успешно выполняется, если файл 7 не был закрыт. Я думаю, что вам нужно утверждение endfile и / или выражение перемотки между записью и чтением.

Пол Томблин (Paul Tomblin) опубликовал информацию о том, что вам нужно сделать после того, как вы решите свою проблему с получением чтения для работы.

1 голос
/ 02 ноября 2009

Вы можете читать с ФОРМАТОМ (А1)? Прошло 20 лет, поэтому я не помню точный синтаксис.

0 голосов
/ 02 ноября 2009

вот несколько подсказок:

  1. Вам не нужно использовать символы , намного меньше файлового ввода-вывода для этой проблемы (если вы не забыли заявить, что файл должен быть создан).
  2. Поэтому используйте математику, чтобы найти статистику . Существует множество ресурсов по числам Фибоначчи , которые могут предоставить упрощенную информацию или, по крайней мере, способ самостоятельно проверить ваши ответы на месте.
    • Вот сложный совет в не-Фортранском жаргоне:
      floor(10^(frac(log_10(7214989861293412))))
      (Поместите это в Wolfram Alpha , чтобы увидеть, что он делает.)
    • Более простой намек (для другого подхода) состоит в том, что вы можете сделать очень хорошо в Фортране с простым арифметика внутри цикла конструкции - хотя бы для первого прохода в решении.
  3. Накапливайте свою статистику как вы идти . Этот совет применим даже к вашему подходу, основанному на характере. (Эта проблема идеально подходит для придумывания симпатичной индексации схема для вашей статистики, но некоторые люди ненавидят милые схемы в программирование. Если ты не боишься остроумие ... тогда вы можете иметь ассоциативный массивы в Фортране, пока ваш ключи являются целыми числами; -)
  4. Самый важный аспект этого проблема в типе данных, которые вы будете используйте для расчета ваших ответов. За Например, вот последний номер, который вы придется печатать .

Ура, - Джаред

0 голосов
/ 02 ноября 2009

Я получаю сообщение об ошибке «конец строки»

Вы не показываете ! code to read here..., из-за чего довольно сложно угадать, что вы делаете неправильно: -)

Возможно, вам нужен цикл для чтения каждой строки, а затем выпрыгнуть из цикла в оператор continue, если строк больше нет.

Примерно так:

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

Еще лучше - посмотрите более современный стиль , используемый в этой программе revcomp .

...