我是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
任何帮助都会很棒。感谢。
答案 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