Fortran 从 if 语句内部写入同一个文件

Posted

技术标签:

【中文标题】Fortran 从 if 语句内部写入同一个文件【英文标题】:Fortran write to same file from inside if statement 【发布时间】:2016-01-25 11:37:29 【问题描述】:

我目前正在处理一些 fortran 代码并遇到错误。

 `Duplicate statement label 201 at (1) and (2)`

我的代码很长,但简化后看起来像这样:

      integer :: y,x,method
      x = 0
      print*, "Please enter a value (1 or 2)." 
      read(*,*) method
          if (method .EQ. 1) then
            x = 10
              do i=1,1000
                 y = x * i
                 Call OtherFile(y,x,i)
                 write(6,201) long,list,of,variables
201      format('OUTPUT: ',i5,1p,7d10.2)
              enddo
              stop
          else if (method .EQ. 2) then
           x = 10
              do i=1,1000
                y = x * i * i
                Call OtherFile(y,x,i)
                write(6,201) long,list,of,variables,
201       format('OUTPUT: ',i5,1p,7d10.2)
            enddo
          stop
        end if

编辑:在之前发布之后,我意识到这段代码可以工作。我无法发布原始作品,所以我最好尝试重现问题。 Edit2:我错误地将其标记为 Fortran77,它实际上是一个旧版本,因为它是用穿孔卡片格式编写的。

有问题的行是以 201 开头的行。

我可以通过在每个 FORMAT 部分之前分别选择 201 和 202 来解决此问题,但是还有其他文件依赖于参数 201 作为语句编号。

谁能告诉我有没有办法解决这个问题?

【问题讨论】:

您的代码没有显示任何标记为201 的格式语句。请查看其中有多少以及它们在哪里/放置在哪里。 [但我可能会感到困惑,因为您似乎希望这些标签指的是文件而不是格式?] 您可以使您的文件更短,但它必须重现问题!取实际代码,删掉东西,等够短了,还是有问题,贴在这里。不要在这里发布任何不包含问题的代码。阅读***.com/help/mcve 有点旁白,但由于无论method 是什么,您都点击了相同的write,因此您应该在if 块之后使用单个write 语句。顺便说一句,您误认为“名为201的文件”。 201是对格式语句的引用,与文件名或单位无关。 我在发布代码后意识到缩短的版本可以工作,所以我已经更详细地介绍了并且最好尝试重新创建问题。由于我无法发布原始作品,我意识到我在匆忙尝试解决这个问题时错过了重要部分。 如错误消息所述,您有两个标记为 201 的语句。这是不允许的。此外,那些标记为201 的语句不是有效的格式语句。 (实际上,它们根本不是有效的陈述。)您期望/希望发生什么? [最后一点,除了201 问题之外,您根本没有 Fortran 77 代码。] 【参考方案1】:

我认为这需要一个不适合评论的完整解释。 FORMAT 不是可执行语句。它只是指示编译器以哪种格式打印或读取 DATA。在给定范围内,始终只能有一个具有相同标签的 FORMAT 语句。究竟在哪条线上并不重要。

特别是在执行writeprintread语句时,程序不会以任何方式跳转到FORMAT语句。编译器只使用那里定义的格式描述。

因此:

          write(6,201) something
201       format('OUTPUT: ',i5,1p,7d10.2)

201       format('OUTPUT: ',i5,1p,7d10.2)
          write(*,201) something

201       format('OUTPUT: ',i5,1p,7d10.2)

          !many lines here

          write(*,201) something

          write(*,201) something

          !many lines here

201       format('OUTPUT: ',i5,1p,7d10.2)

  write(*,"('OUTPUT: ',i5,1p,7d10.2)") something

  write(*,"(i5,1p,7d10.2)") 'OUTPUT: ', something

都会做同样的事情,一切都会很好。

在 write 语句中使用字符常量(或变量)而不是 FORMAT 语句标签的最后一种方式是现代方式。

【讨论】:

感谢回复,我明白了。【参考方案2】:

format 语句不是可执行语句。除非如下所述,它们在代码中的位置并不重要。因此,虽然将格式与输出语句放在一起可能很诱人

      write(6,201) long,list,of,variables
201   format('OUTPUT: ',i5,1p,7d10.2)

这不是必需的。如果稍后想要复制该输出,简单地复制这两行并没有帮助:显示的错误消息可能会弹出。

详细说明:write(unit=6,fmt=201)(为清楚起见添加了关键字)要求使用标记为201format 语句的格式写入单元6,该语句出现在与write 相同的包含范围内。后面一行201 format (...) 提供了这样的东西。

错误是同一范围内的两条语句不能具有相同的标签。删除其中一个,或更改标签(及其引用)将是合适的。

Vladimir F 的回答更详细地介绍了解决格式重用的其他方法。

【讨论】:

我担心你只留下评论,OP仍然一头雾水。 感谢您的回复。我现在已经实现了这一点。代码运行良好,有时它让我很简单。

以上是关于Fortran 从 if 语句内部写入同一个文件的主要内容,如果未能解决你的问题,请参考以下文章

在 Fortran 中写入现有文件而不覆盖

如何在fortran中的特定行写入

如何在 Fortran 派生类型或类中实现类型绑定写入语句输出

Shell条件判断语句与if

是否有可能将“include”转移到fortran的模块中?

fortran77 长语句如何换行