Generalized I/O
Mystery of stars
•	I/O statements took the form

      read *, x, y,z
      print *, a,b,c

•	Such I/O is said to be List-directed or in free format
•	user has no control over the appearance of I/O
•	No flexibility over the I/O devices
•	Keyboard input
•	Display unit output
•	* indicates no control or default format
Mystery resolved
•	* stands for (*,*)
•	In general, it will be (arg1,arg2)
•	arg1 used to select the I/O device
–	* indicates default devices (keyboard and monitor)
•	arg2 controls the I/O formatting
–	It is a string constant
–	* means default formatting
Files
•	I/O through files is the most convenient
•	Standard I/O is very painful for large data
•	Large amount of data can be stored and retrieved with ease
•	Output of one program can be used as input to another
•	The programs need not be running at the same time
•	Once created they remain - permanent memory
•	Files are high level software abstractions of these permanent memory devices
•	They are called as secondary memory
Secondary Memory
•	permanent, slow and large volume of data
•	Some kind of magnetic memory –
•	no power required to retain unlike main memory
•	different kinds - Hard Disks, Floppy Disc, CDs, Magnetic Tapes (old)
•	Random or Sequential access
•	details of devices abstracted from application programmers
•	Files are the abstractions
•	Std. I/O are also files
File Organization
•	Fortran programmer's view
•	A simple file is a linear sequence of records
•	Each record is a meaningful piece of data
•	Files are read or written one record at a time
•	Each record is typically a line of data
–	creation of file determines type of data
•	Files can be sequential or random access
•	Random access files require keys
File Operations
•	Opening a file
•	writing or reading a record
•	Rewinding a file
•	Closing a file
•	Valid sequence
–	 (open (read/write/rewind)* close)*
•	File operations translated to OS calls
•	They can fail and graceful recovery possible
File Opening
•	Simplest example is:
			open(unit = 23, file = "input.dat")
•	This commands associates the file input.dat with the number 23
•	This number can be used for reading and writing onto the file

•	Example:	read(23, *) N
			write(23, *) M
•	Unit numbers are system dependent (usually from 1 to 100)
•	unit and file are named parameters
•	Contrast this with positional parameters
Open attributes
•	Many file attributes assume default values in the above
•	to override these, additional parameters to be set
•	action =	READ, WRITE or READWRITE 			           (default)
•	status =	OLD, NEW, REPLACE (default), 			            SCRATCH, UNKNOWN
•	ios = x,  x is assigned a value at the end of the call
		0 - if the operation is successful
		> 0  - otherwise
•	access = "sequential" (default) or "direct"
Some more attributes
•	form = "formatted" (default) or     
               "unformatted“
–	in unformatted form, data stored in some internal representation
–	can not be edited

•	recl = length of each record
–	required for direct access files

•	position = "rewind", "append"
Example
integer:: ierr
open(unit=23, file = "in.dat", status = "old",      
         action = "Read“,  iostat = ierr)

–	opening the existing file "in.dat", for read
–	ierr gets a value > 0 iff failure in opening

Another Example
integer:: ierr
integer:: ut = 34
open(unit= ut, file = "out.dat", status = "new",    
         action = "write“, iostat = ierr)

–	 creating a new file "out.dat
–	 Status = replace would replace the file

One more Example
open(unit= 15, status = "scratch", iostat = ierr)

–	no file name specified - error otherwise
–	default action - reading and writing temporary data
–	erased after the program terminates

Closing a file
•	Close(close_list)
•	Close_list
–	must specify the unit number
–	may specify other clauses
•	the number is released and can be reused in other open statements
•	repeated opening and closing of non scratch files possible
•	scratch file contents lost once they are closed
Reading and Writing
•	files contain sequence of records
•	Each record is read/written using a single read or write operation
•	So we can say that each record occupies a single line
•	Every read statement refers to the successive records
•	Reference to the file through the unit number
•	example:
			read(unit = 16, *) x, y, z
			write(unit = 25, *) "test output=", a, b, c
•	read and write one record to the appropriate file
Read Pointer
•	There can be errors while reading a file
•	There is a read pointer that indicates the next record to be read
•	Every read moves the read pointer to the next record (in sequential access)

Read Error
•	The read pointer may be at the end

•	use istat clause for detecting end of file (EOF)

			Read(16,*, iostat = err) x, y, z

•	If err is non zero then there is an error

•	Use always iostat clause

•	otherwise, program will abort

Other parameters
•	For direct access files, use the argument
    rec = n
•	This reads/writes the nth record

Example:

    write(23,*,iostat = err, rec = 15) i,j

–	write values of i, j to the record 15 of the associated file

Program bubble_sort

	        implicit none

	integer:: N, i, rt_end, index, temp
	! N - the total number of items in the array
       ! i, j - array index variables
 
       integer, dimension(100):: A	
       integer:: err,errf, werr

       open(unit=1, file = "in.dat", & 
                status = "old", iostat = err)
        if (err/=0) then
            print *, "file opening error"
        else	
                 outer: do
	
Program Continued

        read (unit =1, iostat = errf, fmt = * ) N
	read (1, *,  iostat = errf) (A(i),i=1,N)
        if (errf /= 0) exit
        rt_end = N
        inner: do
             if (rt_end <= 1) exit
             index = 0
             do i = 1, (rt_end-1)
                 if (A(i) > A(i+1)) then
                     temp = A(i)
                     A(i) = A(i+1)
                     A(i+1) = temp
                     index = i
                endif
             enddo
             rt_end = index
             end do inner
Program Continued
    open(unit=2, file = "out.dat", &
        status = "old", access = "sequential", &
             iostat = werr)
     print *, (A(i),i=1,N)
      write (2, fmt = *) (A(i),i=1,N)
  end do outer
endif
close(unit=1)
end program

I/O Formatting
•	So far we have used List-Directed I/O Statements (Free format)
			print *, A,B,C
			read *, A,B
•	Fine for small programs and small number of inputs and outputs
•	Many data processing applications manipulate large collection of inputs and outputs
–	Tabulating marks and results
–	preparing mark sheets and reservation charts
•	Pretty printing and Formatted input very essential
•	Fortran has elaborate features for formatting I/O
Format Strings
•	I/O formats can be specified by using format strings
			print fs, A, B,C
			read  fs, C,D
•	fs identifies a format string
–	a constant string
–	a string variable
–	a label that labels a format statement containing the format string
•	Here is an example format strings
			print "I4, I4, I4", A, B, C

•	This prints A, B and C in a row with each being given 4 decimal places
Edit Descriptor
•	I4 is an edit descriptor
•	Format string contains one or more edit descriptors
•	Very many edit descriptors that help print different types of variables
•	Alternate format strings

		Character(len=20):: str
		str = "(I4, I4, I4, I4)”
		write(*, str) a,b,c,d

		read *, 100, a, b, c, d
		100 format ("I4,I4,I4,I4")

		print "4I4", a, b,c,d
I/O buffer
•	I/O done through buffers
•	Buffer is a temporary storage space where every line of characters is composed before doing I/O
•	Line-oriented I/O
•	For reading – input process builds the buffer and gives the buffer content to the program
•	Every print statement composes the output in the output buffer completely before sending for printing on the device
•	Buffers are read/written as per the format statement 
Output Buffer
•	Usually 133 characters long (line-printer output)
•	First character is a control character
–	1  skip to next page
–	Blank single spacing (default when * is used)
–	0 double spacing
–	+ no space – overwriting
•	The rest of the characters are printed
•	Make sure that first character is the intended control character
        print (*,100) n
        100 format (I3)
Behaviour of print statement when n = 25 and n =125
Some descriptors
•	Iw - w columns reserved for printing an integer value includes - if the number is negative
•	5Iw - 5 successive w columns reserved for printing/reading 5 values
•	Iw.m - minimum m digits need to be presented
•	If w not enough then * printed
•	If the number is less than m digits - leading zeros added
 Format Descriptors
•	rFw.d
		r - repeat count
		w - number of columns for the entire number
			(including decimal point and -ve sign)	
		d - number of columns to the right of the decimal point

•	Number appears right-justified
•	Trailing zeros if the no. of digits after decimal point is less than d
•	rounded off if d is more
•	if (w-d-1) is less, then asterisks printed
E-descriptor
rEw.d

   Printing is done in E notation

Print "E11.4", A 

will print -0.1234E-02 when the value of A is 
             1.234 * 10 ** -1

Make sure that

   w > = d + 7
A-descriptor
rA or rAw

if w is more then A is right justifies
if w is less than only first w characters of A are printed

X descriptor

    nX inserts n spaces in the output

T descriptor

   Tc moves to the column number c

rLw 

   used for printing logical variables - w columns are used
   output will be either T or F, right justified
Repetition
Repetition can be applied to groups of descriptors

     2(I6, 2X, 2F10.2)

is used to print/read two groups, each consisting of an integer (6 digits)
and two floating point numbers of size 10

/ operator used for breaking the line

A single write statement can print on more than one line
Descriptor Association
•	print fs, var_list
•	association of format descriptor to a variable is done from left to right
•	if for every descriptor (except print controls) there is a variable and vice versa, then association is simple
•	if less variables then rest of the descriptors discarded
•	if more variables then the printing starts from a fresh line for rest of the variables
•	format strings for these variables start from right most open parenthesis that does not have repetition count
Example
  print (8, 60) j,k,l,m,n
  60 format  (1X,"The value” = , /, (1X, ‘New Line', 2(3X, I5)))

The output is 
	1	             16      24  (column number not printed)
	The value =
	New Line       1       2
	New Line       3       4
	New Line       5

where j - n has the value 1 - 5
Other aspects
•	Formatted reading is similar (see the books/manuals for details)

•	Format strings can be specified in generalized file-based I/O

•	Include the format string in the argument fmt