FORTRAN 77 Простой ввод / вывод - PullRequest
2 голосов
/ 12 ноября 2011

Я новичок в FORTRAN и должен написать программу на FORTRAN 77 для чтения следующего формата из файла перенаправления или стандартного ввода:

[CHARACTER] [REAL] [REAL] [REAL] ... (can have any number of these)
D [INTEGER] (only one of these)
[REAL] [REAL] [REAL] ... (can have any number of these)

Пример ввода может быть:

T 1.0 2.0 3.0
S 1.0 2.0 4.0
Y 3.0 4.0 5.0
D 2
3.0 5.0 6.0
4.5 4.6 5.6

Мой нативный язык - C ++, поэтому я новичок во всей этой идее о том, что оператор read будет автоматически переходить на следующую строку.

Пока у меня есть следующий код:

c234567
      character*1 D
      character*1 LETTER
      real X, Y, Z
      integer lines
      real point1, point2, point3</p>

<p>85     format (3F10.6)
100    format (A1, 5X, F10.6, 5X, F10.6, 4X, F10.6)
990    format (A, I10)</p>

<pre><code>      MAX = 6
      LETTER = 'Z'
      D = 'D'

      read *, LETTER, X, Y, Z

10 если (ПИСЬМО .ne. D), то напишите (6, 100) ПИСЬМО, X, Y, Z прочитайте *, ПИСЬМО, X, Y, Z перейдите к 10, еще к 20 к концу

C ========================================================== 20 строк = aint (X) написать (*, 990) 'LINES:', строки написать (6, 85) X, Y, Z прочитать *, Z написать (6, 85) X, Y, Z end

Как вы можете видеть, я получаю первую часть штрафа ввода, но после этого он вроде как переходит в кашу из-за оператора read: read*, Z идет к следующей строке.В моем конкретном входном файле, указанном выше, я получаю 2 после D и следующие два значения (3.0, 5.0), но я пропускаю 6.0

. Любая помощь будет отличной.Спасибо.

Ответы [ 2 ]

4 голосов
/ 12 ноября 2011

Если вы знаете, что ваши строки никогда не будут превышать максимальную длину, я предлагаю прочитать всю строку, а затем проанализировать строку в соответствии с вашими правилами.

Пример использования максимальной длины строки 1024 символа:

       CHARACTER*1024 line
       CHARACTER letter
100    FORMAT (A)
       READ(*,100) line
       READ(line, *) letter
       IF (letter .eq. 'T') THEN
          ...
       END IF

Может быть, эта техника работает для вас.

0 голосов
/ 12 ноября 2011

Я даже не посмотрел на ваш код, но я бы предложил следующую стратегию:

(1) read the initial character of the line
if not "D" then 
    read reals
    store the line
    loop to (1)
else
    read one integer
    store the line
    break
endif
read lines of reals until end-of-file

Мой фортран очень ржавый, но я верю, что есть конструкции, которые будутпомочь вам с этим.Конечно, модификатор END к READ будет полезен с последним битом.


После небольшого эксперимента я обнаружил, что gfortran, кажется, поддерживает старый трейлинг $ дляусловное обозначение не опережающего ввода и advance='no'.Однако g77 не .Я не могу говорить ни с каким другим компилятором - насколько я знаю, он никогда не был стандартизирован до Fortran 90, где был представлен advance='no'.

Демонстрационный код, который работает в gfortran, но не в g77

      program temp
c234567
      character a
      integer i
      real x, y, z, w(50)

c This or with (*,'(A1 $)')
      read (*,'(A1)',advance='no') a

      if (a .eq. 'D') then
         read (*,*) i
         write (*,*) a, i
      endif

      end

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

Альтернатива - прочитать букву плюсоставшуюся часть строки в большой символьный буфер, затем анализируйте буфер отдельно по строкам

      character a, buf(1024)
      read (*,'(a1, a1024)') a, buf
      if (a .eq. d) then
         read (buf,*) i
      endif
...