为什么在 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,结果与我预期的不一样。当程序为 运行 并且变量 I
和 A(I)
被写入文件output.dat
。我对变量 I
和 A(I)
没有问题,因为它们已成功写入文件 output.dat
。问题出在变量 T
上,它没有出现在终端上,但它被写入文件 input.dat
。好吧,甚至文件 input.dat
中的前一个文件也没有被覆盖。谁能给我建议?
仅供参考,我也尝试过其他编译器(使用 Windows OS),例如:
- Microsoft Fortran Powerstation(非常老的那个):但它的工作方式和我预期的一样。
- 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,...)
这是没有问题的,因为我使用的是 1
和2
。我只是写了这个简单的案例来代表我的真实代码,而没有先检查它。但实际上在我的真实代码中,我使用了 OPEN(UNIT=5,...)
和 OPEN(UNIT=6,...)
两个语句,这在 Fortran 中是不允许的,因为:
UNIT=5
声明了Standard In
,用于从键盘读入数据。
UNIT=6
声明 Standard Out
用于将一般输出打印到屏幕。
UNIT=0
声明 Standard Error
用于将错误消息打印到屏幕。
我以前没有意识到,因为我正在处理很旧的代码,所以 O 需要将它重写成一个较新的版本。所以,为了避免出现问题,就不要使用UNIT=5
、UNIT=6
和UNIT=0
。
我正在编写代码并使用 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,结果与我预期的不一样。当程序为 运行 并且变量 I
和 A(I)
被写入文件output.dat
。我对变量 I
和 A(I)
没有问题,因为它们已成功写入文件 output.dat
。问题出在变量 T
上,它没有出现在终端上,但它被写入文件 input.dat
。好吧,甚至文件 input.dat
中的前一个文件也没有被覆盖。谁能给我建议?
仅供参考,我也尝试过其他编译器(使用 Windows OS),例如:
- Microsoft Fortran Powerstation(非常老的那个):但它的工作方式和我预期的一样。
- 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,...)
这是没有问题的,因为我使用的是 1
和2
。我只是写了这个简单的案例来代表我的真实代码,而没有先检查它。但实际上在我的真实代码中,我使用了 OPEN(UNIT=5,...)
和 OPEN(UNIT=6,...)
两个语句,这在 Fortran 中是不允许的,因为:
UNIT=5
声明了Standard In
,用于从键盘读入数据。UNIT=6
声明Standard Out
用于将一般输出打印到屏幕。UNIT=0
声明Standard Error
用于将错误消息打印到屏幕。
我以前没有意识到,因为我正在处理很旧的代码,所以 O 需要将它重写成一个较新的版本。所以,为了避免出现问题,就不要使用UNIT=5
、UNIT=6
和UNIT=0
。