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

Why does using command PRINT in Fortran overwrite the input file?

我正在编写代码并使用 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,结果与我预期的不一样。当程序为 运行 并且变量 IA(I)被写入文件output.dat。我对变量 IA(I) 没有问题,因为它们已成功写入文件 output.dat。问题出在变量 T 上,它没有出现在终端上,但它被写入文件 input.dat。好吧,甚至文件 input.dat 中的前一个文件也没有被覆盖。谁能给我建议?

仅供参考,我也尝试过其他编译器(使用 Windows OS),例如:

  1. Microsoft Fortran Powerstation(非常老的那个):但它的工作方式和我预期的一样。
  2. MinGW-w64(Windows 的 GCC 版本):但它不能正常工作。

这可能是因为根据您的 platform/compiler/compiler version/compiler 选项的特定组合,单元 1 是控制台的预连接单元。

您的 OPEN 语句将该单元指向您的输入文件。因此,隐式寻址该单元的 PRINT 语句会将它们的输出定向到同一个文件。

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

(不要将单位编号的值硬编码到您的 input/output 语句中 - 它们应始终由变量或命名常量表示,以便可以轻松地 set/changed在一个地方。)

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

  1. UNIT=5声明了Standard In,用于从键盘读入数据。
  2. UNIT=6 声明 Standard Out 用于将一般输出打印到屏幕。
  3. UNIT=0 声明 Standard Error 用于将错误消息打印到屏幕。

我以前没有意识到,因为我正在处理很旧的代码,所以 O 需要将它重写成一个较新的版本。所以,为了避免出现问题,就不要使用UNIT=5UNIT=6UNIT=0