2

私はFORTRANを初めて使用するので、ファイルリダイレクトまたは標準入力から次の形式を読み取るためにFORTRAN77プログラムを作成する必要があります。

[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

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

      MAX = 6
      LETTER = 'Z'
      D = 'D'

      read *, LETTER, X, Y, Z

10 if(LETTER .ne. D) then write (6, 100) LETTER, X, Y, Z read *, LETTER, X, Y, Z goto 10 else goto 20 endif

C ===================================================== 20 lines = aint(X) write (*,990) 'LINES: ', lines write (6, 85) X, Y, Z read *, Z write (6, 85) X, Y, Z end

ご覧のとおり、入力の最初の部分は正常に取得されますが、その後、readステートメント(read *、Zは次の行に移動)のために、すべてがどろどろになります。上記の特定の入力ファイルでは、Dの後に2があり、次の2つの値(3.0、5.0)がありますが、6.0はスキップしています。

どんな助けでも素晴らしいでしょう。ありがとう。

4

2 に答える 2

3

行が最大長を超えることは決してないことがわかっている場合は、行全体を読んでから、ルールに従って行を解析することをお勧めします。

最大行長1024文字を使用する例:

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

たぶん、このテクニックはあなたのために働くでしょう。

于 2011-11-12T17:33:06.903 に答える
0

私はあなたのコードを見たことがありませんが、私はこのような戦略を提案します

(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

私のFortranは非常に錆びていますが、これに役立つ構造があると思います。確かに、ENDtoの修飾子READは最後のビットで役立ちます。


少し実験した後、それは非前進入力規則gfortranの古い末尾をサポートしているように見えることがわかりました。ただし、しません。私は他のコンパイラと話すことはできません-私が知る限り、これはFortran90が導入されるまで標準化されていませんでした。$ advance='no'g77 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
于 2011-11-12T16:59:34.223 に答える