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