Standard input and output units in Fortran 90?
Solution 1
If you have a Fortran 2003 compiler, the intrinsic module iso_fortran_env
defines the variables input_unit
, output_unit
and error_unit
which point to standard in, standard out and standard error respectively.
I tend to use something like
#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
in my input/output routines. Although this of course means preprocessing your source file (to do this with ifort
, use the -fpp
flag when compiling your source code or change the source file extension from .f
to .F
or from .f90
to .F90
).
An alternative to this would be to write your own, non-intrinsic, iso_fortran_env
module (if you don't have a Fortran 2003 compiler), as discussed here (this link has died since this answer was posted). In this example they use a module:
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
As noted in other answers, 0, 5 and 6 are usually stderr
, stdin
and stdout
(this is true for ifort
on Linux) but this is not defined by the Fortran standard. Using the iso_fortran_env
module is the correct way to portably write to these units.
Solution 2
The Fortran standard doesn't specify which units numbers correspond to stdin/out/err. The usual convention, followed by e.g. gfortran, is that stderr=0, stdin=5, stdout=6.
If your compiler supports the F2003 ISO_FORTRAN_ENV intrinsic module, that module contains the constants INPUT_UNIT, OUTPUT_UNIT, and ERROR_UNIT allowing the programmer to portably retrieve the unit numbers for the preconnected units.
Solution 3
It's actually 0 for stderr. 5 is stdin, 6 is stdout.
For example:
PROGRAM TEST
WRITE(0,*) "Error"
WRITE(6,*) "Good"
END PROGRAM TEST
Gives:
./a.out
Error
Good
while
./a.out 2> /dev/null
Good
I would store a PARAMETER that is STDERR = 0 to make it portable, so if you hit a platform that is different you can just change the parameter.
This example was compiled and run with ifort 12.1.1.256, 11.1.069, 11.1.072 and 11.1.073.
Solution 4
The standard way to write to stdout
in Fortran is to put an asterisk instead of the unit number, i.e.,
WRITE(*,fmt) something
or to simply use
PRINT fmt,something
Similarly, the standard way to read from stdin
is
READ(*,fmt) something
There is no standard way to write to stderr
unless you use ERROR_UNIT
from the ISO_FORTRAN_ENV
module, which requires Fortran 2003 or later.
Unit numbers 0, 5 and 6 will certainly work in the ifort
compiler (and also in some other Fortran compilers), but keep in mind they are compiler-dependent.
AncientSwordRage
I'm just this guy, y'know? (he/him) Secret ninja-muslim programmer, roleplayer and all-round nuisance. Desh by marriage. I have approximate knowledge of many things Cat thumb-servant. I moderate Sci-fi StackExchange, but I'm active on RPG.se, Puzzling.se and I dabble on the writing and worldbuilding StackExchanges. Sci-Fi I used to be the secretary of my university Sci-fi and fantasy club and I love everything from Horror to 'Saturday morning cartoons'. I help moderate this stack (with a diamond), and I'm active/interested in the marvel, back-to-the-future, star-wars and ghostbusters tags. Happy to meet and greet new users, as well as point people in the right direction for story-id questions. RPG TO BE FILLED StackOverflow TO BE FILLED
Updated on October 07, 2020Comments
-
AncientSwordRage over 3 years
How can I read and write to the standard input, output and error streams
stdin
,stdout
andstderr
in Fortran? I've heard writing tostderr
, for example, used to bewrite(5, fmt=...)
, with5
the unit forstderr
, and I know the way to write tostdout
is to usewrite(*, fmt=...)
.How do I read and write to the standard input and output units with the
ifort
compiler?Compiler version:
Intel(R) Fortran Compiler for applications running on Intel(R) 64, Version 10.0 Build 20070426 Package ID: l_fc_p_10.0.023 Copyright (C) 1985-2007 Intel Corporation. All rights reserved