2

我是 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

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

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

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非常生疏,但我相信有一些结构可以帮助您解决这个问题。当然,END修饰符 toREAD将对最后一点有所帮助。


经过一些试验,我发现这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
于 2011-11-12T16:59:34.223 回答