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


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') ' >'

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'

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