【问题标题】:Standard input and output units in Fortran 90?Fortran 90 中的标准输入和输出单元?
【发布时间】:2012-01-20 11:16:57
【问题描述】:

如何在 Fortran 中读取和写入标准输入、输出和错误流 stdinstdoutstderr?我听说写给stderr,例如,使用write(5, fmt=...)5stderr 的单位,我知道写给stdout 的方式是使用write(*, fmt=...)

如何使用ifort 编译器读取和写入标准输入和输出单元?

编译器版本:

英特尔(R) Fortran 编译器,适用于在英特尔(R) 64 上运行的应用程序,版本 10.0 内部版本 20070426 包 ID:l_fc_p_10.0.023 版权所有 (C) 1985-2007 英特尔公司。版权所有

【问题讨论】:

  • ifort 的哪个版本?他们至少支持 F2003 11.1 以后的版本。

标签: fortran stdout stdin stderr fortran90


【解决方案1】:

如果您有 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

在我的输入/输出例程中。虽然这当然意味着preprocessing 您的源文件(要使用ifort 执行此操作,请在编译源代码时使用-fpp 标志或将源文件扩展名从.f 更改为.F.f90.F90)。

另一种方法是编写您自己的非内在 iso_fortran_env 模块(如果您没有 Fortran 2003 编译器),如 here 所述(此链接自发布此答案以来已经死亡)。在这个例子中,他们使用了一个模块:

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 模块是可移植地写入这些单元的正确方法。

【讨论】:

  • @Pureferret 所以你可以使用我建议的替代方法之一。最近的ifort 版本还支持2003 标准的部分内容,包括iso_fortran_env
  • @Pureferret 很高兴听到它有效。预处理可能非常有用,尽管我不经常看到它在 Fortran 代码中使用。
  • 您还可以更改文件的扩展名。如果它是 .F 或 .F90 而不是 .f 或 .f90,那么编译器将为您预处理它而无需特殊标志。
  • @bela83 感谢您指出这一点。我已经更正了我的答案。我很惊讶以前没有人提到过这一点。
  • @Chris 您的链接“预处理”已失效。由于这似乎是答案中相当重要的一部分,请考虑寻找新的链接来源。
【解决方案2】:

Fortran 标准没有指定哪些单元编号对应于 stdin/out/err。通常的约定,后跟例如gfortran,就是stderr=0,stdin=5,stdout=6。

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

【讨论】:

    【解决方案3】:

    stderr 实际上是 0。 5 是标准输入,6 是标准输出。

    例如:

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

    给予:

    ./a.out 
    Error
    Good
    

    同时

    ./a.out 2> /dev/null
    Good
    

    我会存储一个 STDERR = 0 的 PARAMETER 以使其可移植,因此如果您遇到不同的平台,您只需更改参数即可。

    本示例使用 ifort 12.1.1.256、11.1.069、11.1.072 和 11.1.073 编译和运行。

    【讨论】:

    • 我刚刚尝试了 4 个不同版本的 ifort,它可以工作,它也可以与 gfortran 4.6.0、4.6.1 和 4.6.2 一起工作。你能发布它给你的错误吗?
    • 使用 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。保留所有权利。
    • 这是特定于编译器的。 Fortran 9 标准不保证这些数字是 0,5 和 6。
    【解决方案4】:

    在 Fortran 中写入 stdout 的标准方法是用星号代替单元号,即,

    WRITE(*,fmt) something
    

    或简单地使用

    PRINT fmt,something
    

    同样,读取stdin 的标准方式是

    READ(*,fmt) something
    

    没有标准方法可以写入stderr,除非您使用来自ISO_FORTRAN_ENV 模块的ERROR_UNIT,这需要Fortran 2003 或更高版本。

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

    【讨论】:

      猜你喜欢
      • 2014-08-05
      • 2021-10-20
      • 1970-01-01
      • 2013-06-13
      • 2012-03-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-04
      相关资源
      最近更新 更多