Fortran 90中的标准输入输出单元是什么?

34
如何在Fortran中读写标准输入、输出和错误流stdinstdoutstderr?例如,我听说向stderr写入可以使用write(5, fmt=...),其中5stderr的单元,我知道向stdout写入的方法是使用write(*, fmt=...)
如何使用ifort编译器读写标准输入输出单元?
编译器版本:

Intel(R)Fortran Compiler用于在Intel(R)64上运行的应用程序,版本10.0 Build 20070426 Package ID:l_fc_p_10.0.023版权所有(C)1985-2007 Intel Corporation。保留所有权利。


哪个版本的ifort?从11.1版本开始,它们至少支持F2003。 - tpg2114
4个回答

43
如果您有Fortran 2003编译器,则内置模块iso_fortran_env定义了变量input_unitoutput_uniterror_unit,它们分别指向标准输入、标准输出和标准错误。我倾向于使用以下内容:
#ifdef f2003
use, intrinsic :: iso_fortran_env, only : stdin=>input_unit, &
                                          stdout=>output_unit, &
                                          stderr=>error_unit
#else
#define stdin  5
#define stdout 6
#define stderr 0
#endif

在我的输入/输出例程中。当然,这意味着需要对您的源文件进行预处理(要使用ifort进行此操作,请在编译源代码时使用-fpp标志,或将源文件扩展名从.f更改为.F或从.f90更改为.F90)。
另一种方法是编写自己的非内置iso_fortran_env模块(如果您没有Fortran 2003编译器),如此处所讨论的那样(自此回答发布以来,此链接已失效)。在此示例中,他们使用了一个模块:
module iso_fortran_env

  ! Nonintrinsic version for Lahey/Fujitsu Fortran for Linux. 
  ! See Subclause 13.8.2 of the Fortran 2003 standard. 

  implicit NONE 
  public 

  integer, parameter :: Character_Storage_Size = 8 
  integer, parameter :: Error_Unit = 0 
  integer, parameter :: File_Storage_Size = 8 
  integer, parameter :: Input_Unit = 5 
  integer, parameter :: IOSTAT_END = -1 
  integer, parameter :: IOSTAT_EOR = -2 
  integer, parameter :: Numeric_Storage_Size = 32 
  integer, parameter :: Output_Unit = 6 

end module iso_fortran_env

正如其他答案中所指出的那样,0、5和6通常是stderrstdinstdout(这对Linux上的ifort是正确的),但这并不是Fortran标准定义的。使用iso_fortran_env模块是可移植地编写这些单元的正确方法。


1
@Pureferret 所以您可以使用我建议的替代方法之一。此外,最近的 ifort 版本支持2003规范的部分内容,包括 iso_fortran_env - Chris
3
很高兴听到它起作用了。预处理非常有用,尽管我并不经常看到它在Fortran代码中被使用。 - Chris
4
您还可以更改文件的扩展名。如果它是 .F 或 .F90,而不是 .f 或 .f90,那么编译器会为您预处理它,无需特殊标志。 - tpg2114
1
@bela83 感谢您指出这一点。我已经更正了我的答案。我很惊讶之前没有其他人提到过这个问题。 - Chris
1
@Chris,你的“预处理”链接已经失效。由于它似乎是答案中相当重要的一部分,请考虑找到一个新的链接来源。 - River
显示剩余7条评论

17

Fortran标准没有指定哪些单位号对应于stdin/out/err。通常的惯例(例如gfortran遵循)是stderr=0,stdin=5,stdout=6。

如果您的编译器支持F2003 ISO_FORTRAN_ENV内在模块,则该模块包含常量INPUT_UNIT、OUTPUT_UNIT和ERROR_UNIT,允许程序员可移植地检索预连接单元的单元号。


10

实际上,标准错误输出的文件描述符为0。5是标准输入的文件描述符,6是标准输出的文件描述符。

例如:

PROGRAM TEST
  WRITE(0,*) "Error"
  WRITE(6,*) "Good"
END PROGRAM TEST

输出:

./a.out 
Error
Good
< p > 当 < /p >
./a.out 2> /dev/null
Good
我会将一个名为 STDERR = 0 的参数存储起来,以实现可移植性,这样如果你遇到不同的平台,只需更改参数即可。
此示例已使用 ifort 12.1.1.256、11.1.069、11.1.072 和 11.1.073 进行编译和运行。

1
我刚刚尝试了4个不同版本的ifort,它可以工作,并且也可以与gfortran 4.6.0、4.6.1和4.6.2一起工作。你能否发布一下它给你什么错误? - tpg2114
使用 write(0,*) 没有出现任何错误,但是当我将 stderr 重定向到文件时,什么也没有发生。版本为:Intel(R) Fortran Compiler for applications running on Intel(R) 64, Version 10.0 Build 20070426 Package ID: l_fc_p_10.0.023 版权所有 (C) 1985-2007 Intel Corporation。保留所有权利。 - AncientSwordRage
1
这是编译器特定的。在Fortran 9标准中,不能保证这些数字为0、5和6。 - Vladimir F Героям слава

3

在Fortran中,将内容写入stdout的标准方式是将单位编号替换为星号,即:

WRITE(*,fmt) something

或者简单地使用
PRINT fmt,something

同样,从 stdin 读取的标准方法是:

READ(*,fmt) something

如果你使用需要Fortran 2003或更高版本的ISO_FORTRAN_ENV模块中的ERROR_UNIT,那么写入stderr就有了标准方法。

ifort编译器(以及其他一些Fortran编译器)中,单元编号0、5和6肯定可以工作,但请记住它们依赖于编译器。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接