# Console Input/Output

Programs that cannot read input data and write their results to some medium are of little use. We have used print * but there is much more to input/output.

## Console Input/Output

Most operating systems have some type of console. Output written to the console appears as text on a terminal or equivalent. Geany opens a window for console output when a program is executed.

The console in Fortran can be represented with an asterisk *. In Unix this corresponds to the standard input stream for reading, and the standard output for writing. For standard error a file must be associated with it.

Input/output commands can be list directed, where the compiler handles the spacing and other aspects of the appearance of the output, or the programmer can explicitly format the output.

## List-Directed Read/Write from/to the Console

Fortran read from the console. Values may be separated by commas or whitespace:

READ(*,*) var1, var2, var3


READ requires the unit identifier as the first option; here the * indicates console input. The second option must indicate how to format the output, with * telling the compiler to make its own choices. READ can take additional options to check for errors and perform other housekeeping tasks.

IOSTAT=ios


Returns status into the integer variable ios. If the result is zero, the statement succeeded, otherwise it failed. Specific nonzero values are system-dependent.

IOMSG=msg


For IOMSG the specific error message will vary by compiler, and no standard length is specified, but a declared length of 128 should be enough. Use the trim intrinsic to print it more legibly.

ERR=label   !Jump to label on error


Fortran WRITE to the console:

WRITE(*,*) var1,var2,var3


As for READ, the first option to WRITE is the unit identifier and the second is a format descriptor. The asterisk as the format argument specifies a list-directed write in which the compiler formats the output based on its defaults.

WRITE has optional arguments for error checking similar to READ: IOSTAT, IOMSG, and ERR. It also has some optional arguments to control certain aspect of the output appearance, particularly those related to differences in conventional reprsentation of numbers, for example:

DECIMAL=dec


where dec is a character variable or literal that evaluates to COMMMA or POINT. This controls whether floating-point numbers are printed with a comma or decimal point.

The PRINT statement always writes to the console (standard output for Unix). The asterisk specifies list-directed IO.

PRINT *, var1,var2,var3


In Fortran the PRINT statement always writes an end-of-line marker after all variables have been output. The WRITE statement does as well, unless told otherwise. This is the opposite of the behavior of write in most other languages.

Example

program console_io
implicit none
real   ::  x,y

print *, "The product of your numbers is ",x*y
write(*,*,decimal='COMMA') "European style:",x*y

end program



## Reading from the Command Line

Input values can be read from the command line. This is usually accomplished in an IDE through an option to Run.

We can read strings only. You must convert if necessary to a numerical type using internal read/write. See the discussion earlier.

The COMMAND_ARGUMENT_COUNT intrinsic returns the number of command-line options. For each one, we must call GET_COMMAND_ARGUMENT with its number and a character buffer variable.

   nargs=command_argument_count()
if (nargs .ne. 1 ) then
stop "No input specified"
else
call get_command_argument(1,nval)
call get_command_argument(2,mval)
endif


Example:

program console_io
implicit none
character(len=15) :: xvar, yvar
real              ::  x,y
integer           :: nargs

nargs=command_argument_count()
if (nargs .ne. 2) then
stop "Too few arguments."
else
call get_command_argument(1,xvar)
call get_command_argument(2,yvar)
endif

print *, "The product of your numbers is ",x*y
write(*,*,decimal='COMMA') "European style:",x*y

end program



## Exercises

1. In an “infinite” while loop: Request an integer from the user with non-advancing input/output, e.g. “Please enter an integer:” If the integer is 1, print “zebra”. If it is 2, print “kangaroo”. If it is anything else except for zero, print “not found”. If it is 0, exit the loop.
Example Solution

program get_animal
implicit none

integer          :: ans
character(len=8) :: text

do
write(*,*) "Please enter a digit 1 or 2, or 0 to exit:"

if (ans==0) then
exit
else if (ans==1) then
print *, "zebra"
else if (ans==2) then
print *, "kangaroo"
else
endif
enddo

end program



1. Write a program that takes a string as the command-line argument. Print the string to standard output. Use trim or any other string operators or function s to make the output neat. If you read a string from the command line you do not have to do any conversion of the variable.
Example Solution

program read_arg
implicit none

integer            :: nargs
character(len=80)  :: infile

nargs=command_argument_count()
if (nargs .lt. 1) then
stop "No file name specified"
else
call get_command_argument(1,infile)
endif

write(*,'(a,a)') "You entered a file name ",trim(infile)

end program



Previous