Data input/output operations are tightly related to data types. Usually input/output can be from console or from data fields. Data files can be on disk or tape. There are 3 statement for performing I/O.
These operations require format specification, and can output a list of variables, constants or expressions. The arguments are separated by comma.
Data is transferred between the program and devices or files through a Fortran logical unit. Logical units are identified in an I/O statement by a logical unit number, a nonnegative integer from 0 to the maximum 4-byte integer value (2,147,483,647).
The character "*" can appear as a logical unit identifier. The asterisk stands for standard input file when it appears in a READ statement; it stands for standard output file when it appears in a WRITE or PRINT statement.
Unit numbers below 10 are reserved unit numbers for system ussage. You should use > 10 unit numbers when you create or open your own files. These are reserved:
Reading standard input and printing is done using "*". In next example we use them both. Usually the standard input is the console and the application become interactive. I have run this example with and yo can see the results in console.
program main
implicit none
real :: pi
real :: radius
real :: height
real :: area
real :: volume
pi = 3.1415927
print *, 'Cylinder radius:'
read(*,*) radius
print *, 'Cylinder height:'
read(*,*) height
area = pi * radius**2.0
volume = area * height
print *, 'radius is: ', radius
print *, 'height is: ', height
print *, 'base area: ', area
print *, 'volume is: ', volume
end program
>./input
Cylinder radius:
10
Cylinder height:
15
radius is: 10.0000000
height is: 15.0000000
base area: 314.159271
volume is: 4712.38916
>>
Fortran can output data into permanent files. If exist, a file can be open. If does not exist, a file can be created using "open" statement. When a file is open you must specify the logic unit. All other statement need the same unit ID to identify the file you are refering to.
program main
integer :: io ! unit number
integer :: stat ! status number
!check if file exist and remove it
logical :: exists
inquire(file="report.txt", exist=exists)
if (exists) then
open(file="report.txt", newunit=io, iostat=stat)
if (stat == 0) then
close(io, status="delete", iostat=stat)
end if
end if
!create new file report.txt
open(newunit=io, file="report.txt", &
status="new", action="write")
do i=1,10
write(io, *) "row", i
end do
close(io)
end program
>./report
>cat report.txt
row 1
row 2
row 3
row 4
row 5
row 6
row 7
row 8
row 9
row 10
>
Description: In the example above we have open a file called "report.txt" and we have recreated the file. Then we have written 10 rows and then close the file. Ouside of program, we have used command "cat" that is a Bash command to list the report content.
Data format can be simple as "*" that is handled automatically by the system and it supports many variables. Better format is a string containing a set of rule that you can create for different data types:
!fortran example
program main
real:: r = 225.502
integer:: i = 25
character(len=*):: t= "Test"
character(len=*),parameter::&
fmt='(a," ", i5.4," ", f10.5)'
print fmt, trim(t), i, r
end program
>./format
Test 0025 225.50200
Notes: In the example above you can see 3 variables of different kind can be combined using a single format string that has inside 3 specifications separated by comma. You will get many errors until you get the format right. The format is very powerful feature in Fortran. If you learn it right you can create a report quickly from your data.
Rule format is a string with the following convention: It must be enclosed in round brackets like: "( ... )" or '( ... )'. The specification can hold rules and arbitrary text. The text must be enclosed in alternative quotes, "" or '' depending on outer quotes.
Format | Description |
---|---|
"..." | Inserts arbitrary characters. |
Iw[.m] | Read/write w characters as integer number, with optional number of leading zeros m. |
Bw[.m] | Read/write w characters as binary values, with optional number of leading zeros m. |
Ow[.m] | Read/write w characters as octal values, with optional number of leading zeros m. |
Zw[.m] | Read/write w characters as hexadecimal values, with optional number of leading zeros m. |
Fw.d | Read/write floating-point number in decimal notation, with w digits, of which d is the number of decimal places. Sign and floating point must be regarded in w. F0.d allows a variable length. |
Ew.d | Read/write floating-point number in exponential notation, with w characters and a mantissa of d digits.. |
EXw.d[Ee] | Read/write real value in hexadecimal, with field width w, the number of hexadecimal digits in d, and the optional exponent e (Fortran 2018). |
Dw.d | Read/write Floating-point number, double precision. |
A, Aw. | Read/write arbitrary length string, or fixed string with w characters |
Lw | Read/write w characters as logical. |
nX | Read: Ignore the next n characters. |
nX | Write: Print n spaces." |
Tc | Puts next character at position c in line. |
/ | Force a line feed that makes rule o 2 rows. |
The rule can be multiplied like this: nR where n is an integer number. It will create n columns having same rule R. The rule R can start with a capital letter or lowercase letter in modern Fortran. Next example show you such rule:
!fortran example
program main
integer :: io ! unit number
integer :: stat ! status number
!check if file exist and remove it
logical :: exists
inquire(file="mcol.txt", exist=exists)
if (exists) then
open(file="mcol.txt", newunit=io, iostat=stat)
if (stat == 0) then
close(io, status="delete", iostat=stat)
end if
end if
!create new file mcol.txt
open(newunit=io, file="mcol.txt", &
status="new", action="write")
block ! local scope
real(8):: a,b,c,d
call srand(2022) ! initialize
do i=1,20
a=rand(0);b=rand(0)
c=rand(0);d=rand(0)
write(io, "(a, i4.2, 4f8.4)") &
"row", i, a, b, c, d
end do
end block
close(io)
end program
>./mcol
>cat mcol.txt
row 01 0.0158 0.9694 0.8340 0.3906
row 02 0.2554 0.7355 0.1242 0.6645
row 03 0.5373 0.9490 0.4412 0.2599
row 04 0.2119 0.9048 0.0994 0.0538
row 05 0.0641 0.5657 0.2664 0.1550
row 06 0.1566 0.6544 0.9108 0.3426
row 07 0.9495 0.4500 0.9530 0.2241
row 08 0.1507 0.8074 0.6687 0.1644
row 09 0.6800 0.9732 0.3576 0.6896
row 10 0.1952 0.4620 0.8776 0.7148
row 11 0.5126 0.7167 0.2193 0.2855
row 12 0.3706 0.9709 0.1654 0.8778
row 13 0.4196 0.4239 0.8524 0.9736
row 14 0.7799 0.8616 0.4338 0.6776
row 15 0.7381 0.0610 0.4188 0.4611
row 16 0.2086 0.1453 0.9424 0.0846
row 17 0.9904 0.8209 0.1442 0.4619
row 18 0.3793 0.1206 0.4297 0.7354
row 19 0.2594 0.7389 0.1492 0.1095
row 20 0.6615 0.2698 0.7818 0.3536
>
Read next: Data Structures