!
!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
!
!         <<<<<---------------------------------------------->>>>>
!         <<<<<      8. D A T A    T R A N S F E R           >>>>>
!         <<<<<         A N D   O P E R A T I O N S          >>>>>
!         <<<<<         O N   E X T E R N A L  F I L E S     >>>>>
!         <<<<<---------------------------------------------->>>>>
!
!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&

!
! Format specification
!
! The conversion from the internal representation to the external form 
! is carried out according to the information specified in the FORMAT 
! descriptor

! Example
!
! I10        I stands for INTEGER conversion and 10 specifies the 
!            width of the output field
!
! F10.3      F stands for FLOAT, 10 specifies the 
!            width of the output field and 3 the number of figures in
!            the fractional part of the number
!
! A format consists either of a list of descriptors enclosed in 
! parentheses

 '(fF10,3,I4)'

! or a FORMAT statement, referenced by a statement label

 10 FORMAT (F10.3,I4)

! Examples
!

 PRINT*, X,I                     ! Unformatted output

    PRINT '(fF10,3,I4)', X,I     ! Formatted output
    PRINT 10, X,I                ! Formatted output
 10 FORMAT (F10.3,I4)            ! Format descriptor



!+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++  
! 
! I/O LISTS
!
! The quantities to be read or written by a program are specified 
! in an I/O list. 
!
! Examples are below, using also REPEAT COUNT in front of those
! format descriptors that are required repeatedly
!

  INTEGER I
  REAL, DIMENSION(10) :: A
  CHARACTER (LEN=20) WORD

  PRINT '(I10)',      I
  PRINT '(10F10.3)',  A
  PRINT '(3F10.3)',   A(1),A(3),A(5)
  
  PRINT '(5F10.3)',   (A(I),I=1,9,2)
  
  PRINT '(A10)',      WORD(5:14)

! All these examples could be equally be valid in input statements 
! usingthe READ statements 

  READ '(I10)' I

! If an array appears as an item, it is treated as its elements 
! were specified in array element order. 
!
! Example 

  PRINT '(3F10.3)',   A(1),A(2),A(3)  

! This could be equally rewritten as
!
 
  PRINT '(3F10.3)',   A(1:3)

! Analogously 

  PRINT '(3F10.3)',   A(1),A(3),A(5) 

! is equivalent to 
 
  PRINT '(3F10.3)',   A(1:5:2)

!+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
!
! Derived type I/O
!
! An item of the derived type is treated as the components were 
! specified in the type declaration. For example
!

  TYPE POINT 
         REAL, X,Y
  END TYPE POINT 
  
  TYPE(POINT) A
  READ '(2F10.4)' A
  
! the read statement is equivalent to 

  READ '(2F10.4)' A%X, A%Y


!+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
!
! FORMAT DEFINITION
!
! There are 3 ways in which a format specifications may be given
!
!
! 1. A statement label referring ot a FORMAT statement containing 
!    the relevant specifications between parentheses
!
! Example

     PRINT 100, Q
     ...
     ...
 100 FORMAT (F10.3)

! The format statement must appear in the same unit BEFORE the 
! CONTAINS statement (if present). 
!
!
! 2. A character expression whose value commences with a format 
!    specifiation in parentheses
!
! Example

 CHARACTER(LEN=*), PARAMETER :: FORM='(F10.3)'
 PRINT FORM, Q

! Since strings can be concatenated, it is possible to program formats 
! in a flexible way (a given format can be built up dynamically at 
! execution time from different components).
!
! 
! 3. An asterisk (known as list-directed). Useful for small quantities 
!    of items 
!
!

!+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
! UNIT NUMBERS
!
! A Fortran code regards each external medium (essentially either 
! the disk drive or the screen) from which it reads or to which 
! it writes as a UNIT. All program units that refer to a particular 
! UNIT number indeed are referencing the same file. 
!
! GENERAL SYNTAX
!
! READ  (u,fmt) list
! WRITE (u,fmt) list
! 
! where u can be 
!
! 1. an integer between 1 and 99 referencing the UNIT

  READ (4, '(F10.3)' ) Q
  
! 2. an asterisk, this is the standard input designated by the 
!    system

  READ (*, '(F10.3)' ) Q
  
! 3. a character variable (this identifies an internal file)
!
  READ (BUFFER, '(10I6)' ) M
  
! fmt is a format descriptor 
!
! list is a comma-separated item list
!

!+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
! FORMATTED I/O
!
!
! READ  ([UNIT=]u, [FMT=]fmt [,ERR=error-label][,END=end-label]) list
!
! WRITE ([UNIT=]u, [FMT=]fmt [,ERR=error-label]) list


! If the END= is specified, then end-label must be a statement label 
! in the same program unit to which control will be transferred 
! after the end of file is reached

! If the ERR= is specified, then err-label must be a statement label 
! in the same program unit to which control will be transferred 
! if an error is encountered in writing or reading 

! Examples

    SUBROUTINE READ_DATA(X,N,NIN)
      INTEGER IC, NIN
      REAL, DIMENSION(:) :: X
      IC = 0
 10   IC = IC + 1
      READ (NIN, 100, END=20) X(IC)
      GO TO 10
 20   N=IC-1
100   FORMAT (F10.3)
    END SUBROUTINE 


!+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
! DATA EDIT DESCRIPTORS
!
! * INTEGERS
! 
! The descriptor is either 
!
! Iw

  I5
  I10
!
! where w is an integer specifying the length of the field, or 
!  
! Iw.m
!
! This specifies that at least m digits are to be output. For example 
! Output of the integer 99 under control of the descriptor I5.3
! would give 
!
! bb099    ( b is a blanck character)
!
 
! * REAL VALUES
!
! The most common descriptors are F (float) and E (exponential) 
! 
! The general form is 
!
! Fw.d   and Ew.d
!
! where w is the width of the field and d is the number of digits in 
! ths fractional part
!
! Examples
!

  X = 0.723723
  PRINT '(F10.5)', X   

! would produce bb0.723723
! 


  X = 0.723723
  PRINT '(F10.3)', X   

! would produce bbbb0.7237
!


  X = 0.723723
  PRINT '(E10.3)', X   

! would produce b0.723E+00
!

! * COMPLEX VALUES
!
! Complex values may be edited under control of pairs of F or E 
! descriptors (which do not need to be indentical)
!
! Example
!
  COMPLEX C
  C = (0.1,100.)
  PRINT '(F6.1,E8.1)', C

! would give 
!
! bbb0.1b1.0E+02    (try this!)
!
!

! * LOGICAL VALUES
!
! Complex values may be edited using the Lw descriptor (w is the width)


! * CHARACTERS
!
! Characters are edited under control of the descriptor A or Aw (w is 
! the length of the character). 
!
! In the first case, the width of the input or output is determined 
! by the actual width of the item. 


! * GENERAL I/O
!
! The descriptor Gw.d can be used for all data types 
!
! For integers it is equivalent to  Iw
! For reals it can be equivalent to Fw.d or Ew.d depending on the 
! field width and the number of figures d in the fractional part 

!  * DERIVED TYPE
!
! Derived type are edited under control of the appropriate sequence
! of descriptors corresponding to the intrinsic type of the 
! ultimate components of the derived type. 

! Example
!
  TYPE STRING 
      INTEGER LENGTH
      CHARACTER(LEN=20) WORD
  END TYPE STRING  
  TYPE(STRING) :: TEXT
  READ (*,'(I2,A)') TEXT
  

!+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
! OPEN STATEMENT
!
!
! The OPEN statement is used to connect an external file to a UNIT,
! create a file and connect it to a unit or change certains properties
! of the connection
!
! The syntax is 
!
! open ([UNIT=]u [,olist])
!
! u is a SCALAR INTEGER expression
! olist is a list of optional specifiers, all scaler integers or
! characters of default kind
!
! The specifiers are :
!
! IOSTAT = ios, where ios is a default integer variable which is 
!          set to zero if the statement is correctly executed 
!          and to a positive value otherwise
!
! ERR = error-label, causes the control to be transferred to the 
!       statement carrying the label error-label if an error occurs
!
! FILE = fln, where fln is a character expression that provides 
!        the file name (any trailing blanck characters are ignored)
!
! STATUS = st, where st is a chacter expression that may be 
!         
!          OLD, NEW, REPLACE, SCRATCH, UNKNOWN
!
!          The FILE = specifier must be present if st=OLD,NEW or
!          REPLACE. It mnust not be present if SCRATCH is used.
!
!          * If OLD is specified, the file MUST already exist
!          * If NEW is specified, the file must NOT already exist
!            but wil be brought into existence by the action of the 
!            OPEN statement
!          * If REPLACE is specified and the file does not already 
!            exist, the file is created. If the file exists, it is
!            deleted and a new file is created with the same name.
!          * If SCRATCH is specified, the file is created and becomes 
!            connected but it cannot be kept after completion of 
!            the program.
!          * If UNKNOWN the status of the file is processor dependent
!            This is the default value if the STATUS specifier is 
!            omitted
!
! ACCESS = acc, where acc is a character expression that provides 
!          the value SEQUENTIAL or DIRECT (we will not be concerned
!          here with DIRECT access read/write actions).
!
! POSITION = pos, where pos is a character expression that provides
!            the values ASIS, REWIND or APPEND. The access method
!            must be sequential. A new file is positioned at its 
!            initial point. If REWIND is specified, the file is 
!            positioned at its initial point. If APPEND is specified
!            and the file exists, it is positioned ahead of the EOF
!            (end-of-file) record. The default is ASIS.
!
!=======================================================================
! NOTE: The OPEN statements in a program are best collected together 
!       in one place so that any changes that need to be made (e.g. 
!       when transporting the program from one system to another) 
!       can be done smoothly without having to search for them 
!       Regardless of where they appear, the connection may be 
!       referenced in any program unit of the program.
!=======================================================================
!
! Example
!
    PROGRAM MAIN
    CHARACTER(LEN=100) file_name
    .... 
    
    OPEN (1, FILE=file_name, ERR=10, STATUS='new' )
    ! ou OPEN (1, FILE='file.dat', ERR=10, STATUS='new' )
    ....
    ....
    STOP
 10 PRINT*, ' ERROR: THE FILE EXISTS ALREADY'
    END 
    
!+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
! CLOSE STATEMENT
!
! The purpose of the close statement is to disconnect a file from 
! a unit. THe syntax is
!
! CLOSE ([UNIT=]u[,IOSTAT=ios][ERR=error-label][STATUS=st])
!
!
! STATUS=st, where st is a character that may be either KEEP 
!            or DELETE. In the first case the file is kept existing
!            in the second case, the file no longer exists (in 
!            the program). In either case the unit is free to be 
!            connected again to a file.
!
! Hence the basic form of the CLOSE statement is 
!
! CLOSE (u)
!
! Example
!
!
      PROGRAM MAIN
      REAL, DIMENSION(100,10) :: X

      .....
         
      OPEN (1, FILE='data1.dat', ERR=10 )
      DO I=1, N
         WRITE (1,1000) X(I,2:5)
      END DO    
      CLOSE (1)

      ..... ! X is modified for example

      OPEN (1, FILE='data2.dat', ERR=10 )
      DO I=1, N
         WRITE (1,1000) X(I,2:5)
      END DO    
      CLOSE (1)

      .....
      
 1000 FORMAT (4G16.8)
      END PROGRAM


!+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
!      
