FORTRAN 77简单的输入/输出

时间:2011-11-12 16:23:09

标签: fortran fortran77

我是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 ++,所以我对读取语句的整个想法自动转到下一行。

到目前为止,我有以下代码:

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,以及接下来的两个值(3.0,5.0),但我跳过了6.0

任何帮助都会很棒。感谢。

2 个答案:

答案 0 :(得分:4)

如果您知道您的线路永远不会超过最大长度,我建议您阅读整行,然后根据您的规则解析线路。

最大行长度为1024个字符的示例:

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

也许这种技术适合你。

答案 1 :(得分: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

我的堡垒非常生锈,但我相信有一些结构可以帮助你解决这个问题。当然,END READ修饰符对最后一位有帮助。


经过一些小实验,我发现gfortran似乎支持旧的尾随$,用于非推进输入约定 advance='no'。但是,g77 不会。我不能和任何其他编译器说话 - 据我所知,直到引入advance='no'的fortran 90之前,它从未标准化。

适用于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