# Redirecting unit \* to a file

**URL:** <https://fortran-lang.discourse.group/t/redirecting-unit-to-a-file/2822>\
**Category:** Help\
**Created:** [February 18, 2022, 8:45pm UTC](https://fortran-lang.discourse.group/t/redirecting-unit-to-a-file/2822 "2022-02-18T20:45:33Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![feenberg](https://avatars.discourse-cdn.com/v4/letter/f/c2a13f/32.png) [@feenberg](https://fortran-lang.discourse.group/u/feenberg)\
**Post date:** [February 18, 2022, 8:45pm UTC](https://fortran-lang.discourse.group/t/redirecting-unit-to-a-file/2822/1 "2022-02-18T20:45:33Z")

</div>

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](https://docs.oracle.com/cd/E19957-01/805-4939/6j4m0vnaf/index.html) allow a \* in the open statement:

[UNIT=] u

- **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 \*.

---

<div class="post-metadata">

**Author:** ![Beliavsky](https://avatars.discourse-cdn.com/v4/letter/b/ba8739/32.png) [@Beliavsky](https://fortran-lang.discourse.group/u/Beliavsky)\
**Post date:** [February 18, 2022, 8:49pm UTC](https://fortran-lang.discourse.group/t/redirecting-unit-to-a-file/2822/2 "2022-02-18T20:49:00Z")

</div>

> [@feenberg](#):
>
> 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?

Why not use `input_unit` from module [ISO\_FORTRAN\_ENV](https://gcc.gnu.org/onlinedocs/gfortran/ISO_005fFORTRAN_005fENV.html) of Fortran 2003?

---

<div class="post-metadata">

**Author:** ![urbanjost](https://avatars.discourse-cdn.com/v4/letter/u/0ea827/32.png) [@urbanjost](https://fortran-lang.discourse.group/u/urbanjost)\
**Post date:** [February 19, 2022, 3:47am UTC](https://fortran-lang.discourse.group/t/redirecting-unit-to-a-file/2822/3 "2022-02-19T03:47:25Z")

</div>

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.

```fortran
program readfrom
use,intrinsic :: iso_fortran_env, only : &
 & stdin=>input_unit, &
 & stdout=>output_unit,&
 & stderr=>error_unit
implicit none
integer :: count, argument_length, lun, ios
character(len=:),allocatable :: filename
character(len=256) :: line, msg
   ! get number of arguments
   count = command_argument_count()
   if(count.ne.0)then
       call get_command_argument(number=1,length=argument_length)
       ! allocate string array big enough to hold command line argument 
       allocate(character(len=argument_length) :: filename)
       call get_command_argument(1, filename)
       open(file=filename,newunit=lun)
   else
       lun=stdin
   endif
   read(lun,'(a)',iostat=ios,iomsg=msg)line
   if(ios.eq.0)then
      write(*,*)'READ :',trim(line)
   else
      write(*,*)'<ERROR>',trim(msg)
   endif

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.

---

<div class="post-metadata">

**Author:** ![feenberg](https://avatars.discourse-cdn.com/v4/letter/f/c2a13f/32.png) [@feenberg](https://fortran-lang.discourse.group/u/feenberg)\
**Post date:** [February 19, 2022, 12:33pm UTC](https://fortran-lang.discourse.group/t/redirecting-unit-to-a-file/2822/4 "2022-02-19T12:33:18Z")

</div>

Thanks. Another demonstration that there is no problem in computer science that can not be solved with an additional level of indirection.

---

<div class="post-metadata">

**Author:** ![sblionel](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/sblionel/32/853_2.png) [@sblionel](https://fortran-lang.discourse.group/u/sblionel)\
**Post date:** [February 19, 2022, 4:40pm UTC](https://fortran-lang.discourse.group/t/redirecting-unit-to-a-file/2822/5 "2022-02-19T16:40:54Z")

</div>

If you are using Intel Fortran and the ISO\_FORTRAN\_ENV constants, be sure to compile with -standard-semantics. If you don’t, the compiler will use various negative unit numbers for unit \* (or PRINT).

---

<div class="post-metadata">

**Author:** ![msz59](https://avatars.discourse-cdn.com/v4/letter/m/3d9bf3/32.png) [@msz59](https://fortran-lang.discourse.group/u/msz59)\
**Post date:** [February 19, 2022, 6:21pm UTC](https://fortran-lang.discourse.group/t/redirecting-unit-to-a-file/2822/6 "2022-02-19T18:21:38Z")

</div>

> [@sblionel](#):
>
> compiler will use various negative unit numbers for unit \* (or PRINT).

Would that make any difference in a program like above @urbanjost’s sample?

---

<div class="post-metadata">

**Author:** ![sblionel](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/sblionel/32/853_2.png) [@sblionel](https://fortran-lang.discourse.group/u/sblionel)\
**Post date:** [February 19, 2022, 6:32pm UTC](https://fortran-lang.discourse.group/t/redirecting-unit-to-a-file/2822/7 "2022-02-19T18:32:28Z")

</div>

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