我多年前使用过FORTRAN,并且最近负责维护一个旧的FORTRAN程序(F77)。以下代码不熟悉:
READ(FILE_LOG_UNIT, IOSTAT=FILE_STATUS) NUM_WORDS,
. ( BUFFER(BIX), BIX=1, NUM_WORDS )
回顾一些在线论坛后发现,让我感到困惑的部分,即延续线,是一个隐含的循环。由于我的程序在这里给我带来麻烦,我想将其转换为传统的DO循环。转换它也可能有助于下一个从现在起5年后冷却这个东西的可怜的邋!!无论如何,我对DO循环等效的最好猜测是
READ(FILE_LOG_UNIT, IOSTAT=FILE_STATUS) NUM_WORDS
DO BIX=1, NUM_WORDS
READ(FILE_LOG_UNIT, IOSTAT=FILE_STATUS) BUFFER(BIX)
ENDDO
但是,当我只进行此更改时,正在运行的测试用例停止工作。我仍然觉得这里发生的是两个不同的READ(第一个获得NUM_WORDS,第二个循环数据),所以我尝试了一个不那么激烈的改变,将它转换为两个语句,但保留隐含的循环:< / p>
READ(FILE_LOG_UNIT, IOSTAT=FILE_STATUS) NUM_WORDS
READ(FILE_LOG_UNIT, IOSTAT=FILE_STATUS) ( BUFFER(BIX), BIX=1, NUM_WORDS )
但是这种改变也会导致好的测试用例失败。在我的两次修改中,NUM_WORDS的值都按预期通过,所以似乎循环就是失败的地方。
那么,原始隐含循环的等效DO循环是什么?还是我完全走错了路? 感谢
答案 0 :(得分:3)
文件是如何打开的?即它是ACCESS ='顺序',访问='直接',或访问='流'(好吧,最后一个不太可能,因为它是F2003添加)。其次,它是格式化还是未格式化?我将假设它是未格式化的顺序,因为在read语句中没有REC =说明符或格式说明符。
您尝试失败的原因是每个读取语句都读取单独的记录。在F2003中引入access ='stream'之前,Fortran I / O完全基于记录,这与我们用于流式传输文件的人略有不同,如大多数其他语言中所见。
未格式化顺序文件的记录通常在记录的每一端用“记录标记”分隔,通常是4个字节,指定记录的长度。所以记录(在磁盘上)可能看起来像
|长度(4字节)| num_words(4个字节?)|缓冲区(1)|缓冲区(2)| ...... |长度|
现在,如果您尝试使用一个READ语句读取num_words,它将正确读取文件中的num_words,然后它将向前跳过,直到下一条记录开始。然后,当您尝试使用单独的READ语句读取缓冲区时,您已经在文件中处于领先地位。
如果你有点作弊并使用F90 +数组语法,你可能会躲过
READ(FILE_LOG_UNIT, IOSTAT=FILE_STATUS) NUM_WORDS, BUFFER(1:NUM_WORDS)
(虽然我不确定你是否被允许在写入的同一语句中引用num_words)