I would like to have a program read from standard in by default or from a file if a specified. I have thought about using unit 5 for input, which I can redirect to a file in an open statement, but I understand 5 isn’t designated as standard input by the Fortran standard. Is that really a problem? Am I likely to run in to users where unit 5 is not standard in? I mean, someone with a Linux, WIndows or Mac machine. I don’t care about anything older than f2c. The program is used by random unsophisticated users, I’d like to put the redirection in the program rather than rely on a shell script I would have to explain.
As it is, the best I can think of to do that fits the standard is to replace each read statement with 2 read statements, one with a * and one with a unit number. Is that the best I can do?
I notice that some compilers such as Oracle Fortran allow a * in the open statement:
u is an integer expression or an asterisk (*) that specifies the unit number. u is required
but does that modify read or write statements? I suppose it doesn’t matter, since so few compilers support this. Still, it seems odd if there is no way to redirect unit *.
If you have not used INPUT_UNIT before, here is an example that reads one line from stdin
and echoes it unless a filename is given on the command line, in which case that file is read from instead. This assumes your input file is a text file; reading binary files from stdin is problematic.
use,intrinsic :: iso_fortran_env, only : &
& stdin=>input_unit, &
integer :: count, argument_length, lun, ios
character(len=:),allocatable :: filename
character(len=256) :: line, msg
! get number of arguments
count = command_argument_count()
! allocate string array big enough to hold command line argument
allocate(character(len=argument_length) :: filename)
call get_command_argument(1, filename)
end program readfrom`
so if you entered “readfrom myfile” it would read the first line of file “myfile”; otherwise it would
read a line from stdin. You do not have to rename the variables, but I prefer the names stdin, stdout, and stderr myself.
No - my comment related to @feenberg 's mention of unit *, which is part of the standard language. Specifically, if you expected to open unit INPUT_UNIT and then do READ(*) and have that be the unit you opened, it would not work in Intel Fortran without the standard-semantics option (or -assume noold_unit_star)