为什么在Fortran中使用命令PRINT会覆盖输入文件?

时间:2016-07-23 18:42:24

标签: fortran gfortran

我正在编写代码并在Fortran中使用输入和输出功能。代码看起来像这样(仅用于简化):

PROGRAM TEST

  REAL, DIMENSION(1000):: A
  REAL:: B
  INTEGER::T

 !Defining input and output  
  OPEN(UNIT=1, FILE='input.dat', STATUS='OLD')
  OPEN(UNIT=2, FILE='output.dat', STATUS='NEW')  

 !Reading from file "input.dat"  
  READ(1,*) (A(I),I=1,1000)

 !Just for initial condition
  B=0.0  

  DO T=1, 10
    PRINT *, 'Step =', T 
        DO I=1, 1000     
           B=B+1.0     
           A(I)=A(I)/B  
        END DO
  END DO

 !Writing results into file "output.dat"
   DO I=1, 1000
      WRITE (2,100) I, A(I)
   END DO 
   100 FORMAT (' ',T3, I12, T17, F14.4)   

END PROGRAM TEST

我正在使用Gfortran 5.3,结果不像我期待的那样。当程序运行并且变量TI被写入文件{{1}时,我希望在屏幕(或Ubuntu OS中的终端)上获得变量A(I)的结果}。我对变量output.datI没有问题,因为它们已成功写入文件A(I)。问题在于变量output.dat,它没有出现在终端上,而是写入文件T。好吧,即使文件input.dat中的上一个文件也没有被覆盖。有人能给我这个建议吗?

仅供参考,我还试过其他编译器(使用Windows操作系统),例如:

  1. Microsoft Fortran Powerstation(非常古老的版本):但它的效果与我预期的一样。
  2. MinGW-w64(适用于Windows的GCC版本):但无效。

2 个答案:

答案 0 :(得分:5)

这可能是因为您使用平台/编译器/编译器版本/编译器选项的特定组合,单元1是控制台的预连接单元。

您的OPEN语句将该单位定向到您的输入文件。因此,隐式地处理该单元的PRINT语句然后将它们的输出定向到同一文件。

使用不同的单元号 - 从编译器预连接的单元中选择大于10的值通常是安全的。为了进一步安全起见,您可以使用INQUIRE(UNIT=unit_number, EXIST=some_logical_variable)语句检查特定单元是否连接到OPEN语句之前的文件 - 如果是,则选择不同的单元号。理想情况下,如果您正在编写Fortran 2008,则可以使用NEWUNIT说明符。

(不要将单元号的值硬编码到输入/输出语句中 - 它们应始终用变量或命名常量表示,这样可以在一个地方轻松设置/更改值。)

答案 1 :(得分:1)

我找到了答案。实际上我上面发布的代码在Gfortran 5.3上运行良好,因为我使用了OPEN(UNIT=1,...)OPEN(UNIT=2,...),因为我使用1和{{{ 1}}。我只是写了这个简单的案例来代表我的真实代码而不先检查它。但实际上在我的实际代码中,我使用了2OPEN(UNIT=5,...)存在的两个语句,这些语句在Fortran中是不允许的,因为:

  1. OPEN(UNIT=6,...)声明UNIT=5,用于从键盘读取数据。
  2. Standard In声明UNIT=6,用于将常规输出打印到屏幕上。
  3. Standard Out声明UNIT=0,用于将错误消息打印到屏幕上。
  4. 我之前没有意识到,因为我正在处理相当旧的代码,所以O需要将其重写为更新的版本。因此,为了避免这些问题,请不要使用Standard ErrorUNIT=5UNIT=6