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.
|"..."||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