Unidades de entrada y salida estándar en Fortran 90?


¿Cómo puedo leer y escribir en los flujos de entrada, salida y error estándarstdin, stdout y stderr en Fortran? He oído escribir a stderr, por ejemplo, usado para ser write(5, fmt=...), con 5 la unidad para stderr, y sé que la forma de escribir a stdout es usar write(*, fmt=...).

¿Cómo puedo leer y escribir en las unidades de entrada y salida estándar con el compilador ifort?

Versión del compilador:

Compilador Intel (R) Fortran para aplicaciones que se ejecutan en Intel(R) 64, Versión 10.0 Build 20070426 Identificación del paquete: l_fc_p_10.0.023 Copyright (C) 1985-2007 Intel Corporation. Todos los derechos reservados

Author: Pureferret, 2011-12-14

4 answers

Si tiene un compilador Fortran 2003, el módulo intrínsecoiso_fortran_env define las variables input_unit, output_unit y error_unit que apuntan a standard in, standard out y standard error respectivamente.

Tiendo a usar algo como

#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

En mis rutinas de entrada/salida. Aunque esto, por supuesto, significa preprocesar su archivo fuente (para hacer esto con ifort, use la bandera -fpp al compilar su código fuente o cambie la extensión del archivo fuente de .f a .F o de .f90 a .F90).

Una alternativa a esto sería escribir su propio módulo, no intrínseco, iso_fortran_env (si no tiene un compilador Fortran 2003), como se discute aquí (este enlace ha muerto desde que se publicó esta respuesta). En este ejemplo utilizan un módulo:

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

Como se señaló en otras respuestas, 0, 5 y 6 son generalmente stderr, stdin y stdout (esto es cierto para ifort en Linux) pero esto es no definido por el estándar Fortran. Usar el módulo iso_fortran_env es la forma correcta de escribir portablemente en estas unidades.

 36
Author: Chris,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-11-26 09:40:10

El estándar Fortran no especifica qué números de unidades corresponden a stdin/out/err. La convención habitual, seguida por, por ejemplo, gfortran, es que stderr = 0, stdin = 5, stdout = 6.

Si su compilador soporta el módulo intrínseco F2003 ISO_FORTRAN_ENV, ese módulo contiene las constantes INPUT_UNIT, OUTPUT_UNIT y ERROR_UNIT permitiendo al programador recuperar portablemente los números de unidad para las unidades preconectadas.

 12
Author: janneb,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-12-14 17:19:15

En realidad es 0 para stderr. 5 es stdin, 6 es stdout.

Por ejemplo:

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

Da:

./a.out 
Error
Good

Mientras que

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

Almacenaría un PARÁMETRO que es STDERR = 0 para hacerlo portátil, por lo que si golpea una plataforma que es diferente, puede cambiar el parámetro.

Este ejemplo fue compilado y ejecutado con ifort 12.1.1.256, 11.1.069, 11.1.072 y 11.1.073.

 6
Author: tpg2114,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-07-23 08:53:05

La forma estándar de escribir a stdout en Fortran es poner un asterisco en lugar del número de unidad, es decir,

WRITE(*,fmt) something

O simplemente usar

PRINT fmt,something

De manera similar, la forma estándar de leer de stdin es

READ(*,fmt) something

No hay una forma estándar de escribir en stderr a menos que use ERROR_UNIT desde el módulo ISO_FORTRAN_ENV, que requiere Fortran 2003 o posterior.

Los números de unidad 0, 5 y 6 ciertamente funcionarán en el compilador ifort (y también en algunos otros compiladores de Fortran), pero tenga en cuenta dependen del compilador.

 0
Author: Petr Pařík,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-10-06 20:39:58