Fortran terminal I/O, the ISO standard way
iso_fortran_env
is respected by all common Fortran compilers, as implied by its name.
iso_fortran_env
is part of the Fortran 2003 specification and popular Fortran compilers added it a decade ago (Gfortran since at least GCC 4.3).
Why use iso_fortran_env
terminal I/O: legacy programs written before Fortran 2003 often write to terminal with:
write(*,*) 'The value of X is ',x
or
write(6,*) 'The value of X is ',x
This is a problem when trying to debug with text output to terminal, especially where someone has used “6” for file I/O unit by mistake.
Or, if trying to write to a file with an uninitialized unit number, stderr gets redirected to file fort.0
.
Also you can print repeatedly to the same line, and combine prompt text on the same line with input.
iso_fortran_env
terminal I/O: example prints to stdout
, then stderr
and finally asks for user input with a prompt on the same line.
program myterm
use iso_fortran_env
implicit none (type, external)
character(1000) :: usertxt ! 1000 is an arbitrarily large number
integer :: ios
! could also just use print *,'printed to stdout'
write(output_unit,*) 'Printed to stdout'
write(error_unit,*) 'printed to stderr'
! prompt with caret on same line as input, here using a greater than sign >
write(output_unit,'(A)',advance='no') ' >'
flush(output_unit)
read(input_unit,"(A)", iostat=ios) usertxt
! trap Ctrl-D EOF on Unix-like systems to avoid crashing program
if (ios/=0) backspace(input_unit) ! ctrl D gobble
write(output_unit,*) 'you typed ',usertxt
end program
If stderr goes to file fort.0
If your stderr
from error_unit gets written to a file fort.0
instead of being printed to screen, this is a sure indication that you’re open(u)
ing a file without first setting a value for u
.
Unless needing to persist a file opening between calls of a function/subroutine, you should normally open
a file with newunit
.
program myfile
use iso_fortran_env
implicit none (type, external)
integer :: u, ios
character(1000) :: fn ! 1000 is an arbitrarily large number
character(1000) :: dat
print *, "please input file to open"
read(input_unit,'(A)',iostat=ios) fn
! open file, using better to ask forgiveness than permission principle
! status='old' means generate error if file doesn't exist
open(newunit=u,file=fn, status='old',action='read',iostat=ios)
if (ios/=0) then
write(error_unit,*) 'could not open file ',trim(fn)
error stop 'file IO error'
endif
read(u,'(A)') dat
print *,'first two lines of ',trim(fn),' are:'
print *,trim(dat)
read(u,'(A)') dat
print *,trim(dat)
close(u) ! implicitly closed at end of program, but as good practice...
end program