Reputation: 167
The following fortran code will calculate the area of a circle or a rectangle according to user's input. If there is only one input floating point then it will calculate the area of a circle while if there are two then it will return the area of a rectangle. Currently, I do this by user typing 1 or 2 at first. However, I would like to know if there are direct ways of reading in indefinite # of input parameters in fortran. Please do offer your wisdom. I appreciate it!
module MA
implicit none
interface area
module procedure area_circ ! calculate the area of circles
module procedure area_rec ! rectangles
end interface
contains
real function area_circ(a)
implicit none
real, intent(in) :: a
real, parameter :: pi=3.14159
area_circ = pi*a**2
write(*,"('Area of circle = ',F6.2)") area_circ
return
end function area_circ
real function area_rec(a,b)
implicit none
real, intent(in) :: a,b
area_rec=a*b
write(*,"('Area of rectangle = ',F6.2)") area_rec
return
end function area_rec
end module MA
program hw1101
use MA
implicit none
real :: a,b,S
integer :: i
write(*,*) 'Please type # of parameters: '
read(*,*) i
if(i==1) then
write(*,*) "Please type one parameter: "
read(*,*) a
S=area(a)
else if (i==2) then
write(*,*) "Please type two paramters: "
read(*,*) a,b
S=area(a,b)
else
write(*,*) "Other functions under construction..."
end if
stop
end program hw1101
Upvotes: 0
Views: 173
Reputation: 78314
An up-to-date Fortran compiler provides a number of intrinsic routines for handling command line arguments. You can use the function COMMAND_ARGUMENT_COUNT
to get the number provided when you execute the program, then read them one by one. Perhaps something like this:
CHARACTER(len=16) :: arg
REAL, DIMENSION(4) :: arguments
...
DO ix = 1, COMMAND_ARGUMENT_COUNT()
CALL GET_COMMAND_ARGUMENT(ix,arg)
READ(arg,*) arguments(ix)
END DO
Note that the subroutine GET_COMMAND_ARGUMENT
returns a character variable through the second argument (which I've called arg
). It has other, optional, arguments so you might want to check some documentation.
There's nothing wrong with your current approach for determining which area
function to call but if you wanted to you could also write an area function which takes optional arguments. Here's an example:
REAL FUNCTION area(a,b)
REAL, INTENT(in) :: a
REAL, INTENT(in), OPTIONAL :: b
IF (.NOT.PRESENT(b)) THEN
area = 3.14159*a*a
ELSE
area = a*b
END IF
END FUNCTION area
which should give you the general idea. The attribute OPTIONAL
and the intrinsic logical function PRESENT
are what you need for routines with optional argument. I think the approach you've already taken is actually better.
Upvotes: 3
Reputation: 168
real a, b, s
character(len=20) :: string_in
integer istat
read(*, '(a)') string_in
read(string_in, *, iostat=istat) a, b
if (istat /= 0) then
read(string_in, *, iostat=istat) a
if (istat == 0) s = area (a)
else
s = area (a, b)
end if
Upvotes: 0