program inputOutput

!//////////////////////////////////////////////////////////
!/  programa para ejemplificar el uso de entrada/salidad  /
!/  desde y hacia una "unidad" que puede ser la entrada o /
!/  salida estandar o archivos.                           /
!/  Los comandos para abrir y cerrar archivos son:        /
!/     open y close                                       /
!/  Las sentencias para leer y escribir hacia una unidad: /
!/     read y write (o print)                             /
!/                                                        /
!/  Las sentencias read y write aceptan "formatos" que    /
!/  permiten darle forma a las lineas que se imprimen o   /
!/  leen.                                                 /
!//////////////////////////////////////////////////////////


! Declaro algunas variables
integer(kind=4) :: int1 , int2  
integer(kind=8) :: int3 , int4  
real            :: real1 , real2  
real(kind=8)    :: real3 , real4 
character(len=10) :: string 
character         :: char1 
logical         :: b1 , b2 



!========== FORMATOS de Representacion de Datos ===============

! En Fortran leemos/escribimos datos con el comando read/write
! El formato predeterminado (el * en el segundo elemento de paretesis)
! Utiliza todo el espacio de cifras para los enteros y reales del kind dado

write(*,*)"El formato por defecto, utiliza todo el espacio de cifras para un entero o real de kind dado:"
write(*,*)"Variables de tipo character consecutivas se despliegan una despees de otra sin espacio entre medio "

int1 = -123
int2 = 145
real1 = 1./3.
real2 = 2./3.
real3 = 1._8/3._8
real4 = 2._8/3._8
string = "0123456789"
 char1 = "C"
write(*,*) int1,int2,rea1,real4,string,char1,b1,b2

!//////////////////////////////////////////////////////////////////////
!/  La unidad de registro tantto para lectua/escritura es la linea    /
!/  Una linea puede dividirse en varios "campos" que se deteminan     /
!/  con un "especificador de formato".                                /
!/  Un "especifiador de formato" es una ista de carateres formada por /
!/  uno o mas "especificadores":                                      /
!/     '(especificador1,[especificador2,...])'                        /
!/                                                                    /
!/ Un especificador nos dice como formatear un campo                  /
!/ Los especificadores para variables son:                            /
!/  - Para enteros: In  usa n cifras para el entero                   /
!/  - Para reales (punto fijo): Fn.d  usa siempre d cifras decimales  /
!/                              y n en total                          /
!/  - Para reales (punto fijo de doble precision): Dn.d funciona      /
!/                              igual que el anterior                 /
!/  - Para reales (notacion exponencial): En.d                        /
!/  - Para caracteres: A utiliza el espacio de la cadena              /
!/                     Ad utiliza d caracteres de la cadena           /
!/  - Para logicals: L utiliza un caracter                            /
!/                   Ld utilia d caracteres                           /
!/ Otros especificadores de campo son:                                /
!/  - X : separa con  un espacio el siguiente campo,por lo tanto      /
!/        el nuevo campo tiene un " " al comienzo                     /
!/  - $ : Cuando se ejecuta un read/write la computadora pasa a la    /
!/        siguiente linea, si usamos el "$" ontinua en la misma       /
!/  - / : Opuesto a anterior, indica pasar a una nueva linea          /
!/  - Tn : desplaza a a columna n el siguiente campo                  /
!/  n<especificador> : repite n veces un espeificador                 /           
!//////////////////////////////////////////////////////////////////////

! ejemplos
write(*,*) "====== Ejemplo de Especificadores ========"
print*,

int1 = 1234567890
int4 = 1234567890123456789_8 ! Al final _8 indica que el literal es kind=8 
write(*,*) "E entero int1 de 10 cifras es:"
write(*,'(I10)') int1
write(*,*) "Uso ahora par int1 20 cifras de espacio:" 
write(*,'(I20)') int1
write(*,*) "El int4 kin=8 consume  no mas de 19 cifras"
write(*,*) int4

print*,

real1 = 1./30.
real2 = 1./3.
write(*,*)"real1 y real2 con 5 cifras decimales:"
write(*,'(F10.5)') real1
write(*,'(F10.5)') real2

print*,

real1 = 10000./3.
write(*,*)"Observar que 10000/3 tiene cuatro cifras enteras, pero es kind=4 solo puede tener" &
           ,"7 cifras ignificativas "
write(*,'(F10.5)') real1

print*,

real4 = 2._8/3._8
write(*,*)"real4 es de doble precision y puede tener hasta 16 cifras significativas:"
write(*,'(F18.16)') real4

print*,

real4 = 1._8/300._8

write(*,*) "Se puede usar el En.d o En.dEe para la notación exponenciañ de base 10"
write(*,*) "El exponente puede tener 2 o 3 cifras y signo"
write(*,'(E25.16)') real4

print*,

string = "0123456789"
write(*,*) "El string de 10 caracteres lo despliego con su tamano con 'A':"
write(*,'(A)') string
write(*,*) "El string de 10 caracteres lo despliego con un tamano de 7 con 'A7':"
write(*,'(A7)') string

print*,

write(*,*) "====== Ejemplo de Especificadores compuestos ========"

int1 = 12345
real1 = 1./.3
write(*,'(A,I5,F5.3)') "Los campos se imprimen uno seguido de otro sin espacios",int1,real1
write(*,'(A,X,I5,X,F5.3)') "Los campos se separan uno de otro por un espacio usando la X",int1,real1
write(*,'(A,X,3I5)') "repito el especificador entero de 5 cifras, 3 veces",int1,int1,int1
write(*,'(A,X,3(X,I5))') "Se puede usar identificadores compuestos mas complejos",int1,int1,int1

print*,

write(*,*)"puedo usar varios write para imprimir en una misma linea con $:"
write(*,'(X,I5,X,I5,$)') int1,int1
write(*,'(X,I5,X,I5,$)') int1+1,int1+2

print*,

write(*,*) "Puedo definir un 'label' con el formato para mayor comodidad e invocarlo en el especificador:"

99 format (X,I5,X,I5)
write(*,99) int1,int2  

print*,

write(*,*)" Para la operacion de read es todo analogo,no se pueden igresar datos de mayor tamano que el que permite el tipo:"
write(*,*)"Ingrese un string de tamano 10 o menor y un int de tamano 5 o menos"
read(*,'(A,I5)') string, int1





!========== LECTURA Y ESCRITURA EN ARCHIVOS ==================

!//////////////////////////////////////////////////////////////
!/ Cuando efectuamos una operacion e read/write la hacemos    /
!/ desde/hacia una "unidad" que se identifica con un nro.     /
!/ La entrada/salida estandar se indentifica con 5 y 6        /
!/ respectivamente o con un *. La lectura de stdin es con     /
!/ read(*,*) o read(5,*) y la escritura a stdout es con       /
!/ write(*,*) o write(6,0). Podemos especificar una unidad    /
!/ distinta de 5 o 6 para archivos. Los archivos los abrimos  /
!/ con "open" y lo cerramos con "close" luego efectuamos      /
!/ operaciones dee lectura/escritura con read/write como se   /
!/ vio antes pero hacia la unidad especifica del archivo      /
!//////////////////////////////////////////////////////////////

!ejemplo

int1 = 12345
int2 = 45678
string = "./file"
open(10,file=string)
write(10,100) int1,int2         ! escribo los 2 enteros separados por un espacio, segun el formato 100
write(10,100) int1+1,int2+2
close(10)                       ! cierro earchivo antes de leeero nuevamente

open(10,file=string)            ! lo abro  nuevamente y leo su contenido
do i=1,2
   read(10,100) int1,int2
   write(*,100)int1,int2
end do
close(10)

100 format(X,I5,X,I5)

end program inputOutput