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