Beliavsky / FortranTip

Short instructional Fortran codes associated with Twitter @FortranTip
https://zmoon.github.io/FortranTipBrowser/
The Unlicense
64 stars 14 forks source link

partially reading a list using list-directed input #46

Open urbanjost opened 2 years ago

urbanjost commented 2 years ago

List-directed input (using an asterisk("*") as a format) is often described simply as free-format input but it is more. It allows for null values and reading a partial list , and the form" r*c" where “r” is a repeater.

Suppose you have a program that prompts you for nine values to translate, scale, and/or rotate an object.

program listdirected
implicit none 
real :: x=0.0,y=0.0,z=0.0,  sx=1.0,sy=1.0,sz=1.0, rx=0.0,ry=0.0,rz=0.0
integer :: ios
character(len=256) :: msg, input
   do
      print *, 'Enter transformation value(s) or "stop"'
      print *, 'translate .........',x,y,z
      print *, 'scale .............',sx,sy,sz
      print *, 'rotate (degrees)...',rx,ry,rz
      read(*,'(a)',iostat=ios,iomsg=msg) input
      if(input.eq.'stop')exit
      read(input,*,iostat=ios,iomsg=msg) x,y,z,sx,sy,sz,rx,ry,rz
      if(ios.ne.0)then
         print *,"<ERROR>",trim(msg)
         cycle
      endif
      ! do something
   end do
end program listdirected

You do not have to enter all nine values. To just change all the scaling values to "2.0", you can enter:

  ,,,2,2,2/

Where the null values mean to skip changing that value, and the slash means the end of values, or equivalently

3*,3*2.0/

Where "3" skips three values, 32.0" sets the next three values to two, and the "/" means you are done supplying values.

Beliavsky commented 2 years ago

Thanks -- tweeted.

urbanjost commented 2 years ago

No prob. Maybe someone would like how you can simply NAMELIST group input so you can just use NAME=value with the same special syntax working, with the / not needed so you could run this and simply enter things like

scale=10,2

or "move=,,100" or "scale=3*2"

and you can add your own commands like "stop". I usually add "help", "stop", and "reset" commands. It is a lot nicer to use when you do not have to type "&value" and "/".

program testit implicit none real :: move(3)=[0.0,0.0,0.0], scale(3)=[1.0,1.0,1.0], rotate(3)=[0.0,0.0,0.0] integer :: ios namelist /values/ move,scale,rotate character(len=256) :: input(3)=[character(len=256) :: '&values','','/'], msg do print , 'Enter transformation value(s) or "stop"' print , 'move ..............',move print , 'scale .............',scale print , 'rotate (degrees)...',rotate read(,'(a)',iostat=ios,iomsg=msg) input(2) if(input(2).eq.'stop')exit read(input,iostat=ios,iomsg=msg,nml=values) if(ios.ne.0)then print ,"",trim(msg) cycle endif write(*,nml=values) ! do something end do end program testit

On 05/26/2022 10:38 AM Beliavsky ***@***.***> wrote:

Thanks -- tweeted https://twitter.com/fortrantip/status/1529807207080009729 .

—
Reply to this email directly, view it on GitHub https://github.com/Beliavsky/FortranTip/issues/46#issuecomment-1138649126 , or unsubscribe https://github.com/notifications/unsubscribe-auth/AHDWN3P5IESHVVYXT5HKMTDVL6EF7ANCNFSM5VI3XB4Q .
You are receiving this because you authored the thread.Message ID: ***@***.***>