Pass arguments and take sum - fortran

I am passing two values to my Fortran program, I need to get the sum of those arguments and print it as result:
I have the program for reading arguments as follows:
PROGRAM Argtest
IMPLICIT NONE
integer*4 nargs,i
character arg*80
nargs = iargc()
do i = 0,nargs
call getarg(i, arg)
print '(a)', arg
end do
END
I am passing the values 10 and 20.
I tried like this:
PROGRAM Argtest
IMPLICIT NONE
integer:: nargs,i
character:: arg
integer:: num1
integer:: num2
integer:: result
nargs = iargc()
do i = 1,nargs
call getarg(i, arg)
!print *, arg
IF( i == 1) THEN
num1 = ichar(arg)
ELSE IF(i == 2) THEN
num2 = ichar(arg)
ELSE
end IF
end do
result = num1+num2
print *, num1
print*,num2
END
I need to print the answer as 30. But I am getting values 49 and 50 instead of getting 10 and 30. Please help me.

Here is a very simple version: It reads the arguments as strings, converts them into ints one after the other, and adds them all up.
PROGRAM Argtest
IMPLICIT NONE
integer*4 nargs,i
character arg*80
integer :: total, int_arg
nargs = iargc()
total = 0
do i = 1,nargs
call getarg(i, arg)
read(arg, *) int_arg
total = total + int_arg
end do
print *, "total is ", total
END
Note that I am starting from argument 1, not 0 (as that is your program name, and can't be converted into a number).
You have now updated your question: ichar converts a single character into the integer that corresponds to that character's ASCII code.
You need to use read(ch_num, '(I)') int_num to convert a string like "10" to the integer number 10.

Related

Fortran program to return numbers from Integer input

After Receiving an integer as input from the keyboard, and passing it to a subroutine that should be responsible for returning the first number, how does one loop through the input and get the first value?
If they enter 123456 , I would need to return 6, then 5, then 3, then 1.in different subroutines.
PROGRAM DATING
IMPLICIT NONE
INTEGER :: num, first, second, fourth, sixth ! varialbe declaration
CHARACTER(Len=10) :: output
WRITE *,' What number did prison Ex give you? '
READ *, num
CALL FIRST( + num)
CALL SECOND( + second)
CALL FOURTH( + fourth)
CALL SIXTH( + sixth)
WRITE(output,'(i2.2)')num ! program output
WRITE *, "Use" ! program output
END PROGRAM DATING
SUBROUTINE FIRST(first)
IMPLICIT NONE
RETURN
END SUBROUTINE FIRST
SUBROUTINE SECOND(Second)
IMPLICIT NONE
RETURN
END SUBROUTINE SECOND
SUBROUTINE FOURTH(fourth)
IMPLICIT NONE
RETURN
END SUBROUTINE FOURTH
SUBROUTINE SIXTH(sixth)
IMPLICIT NONE
RETURN
END SUBROUTINE SIXTH
I have tried to develop subroutines to handle each case but looping through input is tricky
If you want to read six integer digits from a string with six digits, you can read them directly:
integer :: digits(6)
read(*,'(6i1)') digits
You can also convert an existing integer number to a string and do the same:
character(6) :: string
write(string,*) num
read(string,'(6i1)') digits
And you can also compute the digits from the integer using division by 10 and remainders after division:
sixth = mod(num, 10)
num = num/10
fifth = mod(num, 10)
num = num/10
...
Or just make a loop and use the digits array. The above just shows the main idea.
You must make sure that there are indeed six digits or implement some checks.

Getting the prime numbers till 10000 in fortran?

Im trying to print prime numbers till 10000. (display the first five for testing)
This is my program
program primes
implicit none
integer :: array(1229)
integer :: i, ind
logical :: is_prime
ind = 1
do i = 2, 10000, 1
if (is_prime(i) .eqv. .true.) then
array(ind) = i
ind = ind + 1
end if
end do
print *, array(1)
print *, array(2)
print *, array(3)
print *, array(4)
print *, array(5)
end program primes
function is_prime(n) result(ispr)
implicit none
integer :: c, i
integer, intent(in) :: n
logical :: ispr
c = 0
do i = 2, n
if (mod(i,2) == 0) then
c = c + 1
end if
end do
ispr = (c == 0)
end function is_prime
I don't know why but this is the output
9175178
6417360
5374044
6750309
7536745
Why does this happen and how to correct?
is_prime should be(n is the only divider of n besides 1 <=> c == 1)
function is_prime(n) result(ispr)
implicit none
integer :: c, i
integer, intent(in) :: n
logical :: ispr
c = 0
do i = 2, n
if (mod(n,i) == 0) then
c = c + 1
end if
end do
ispr = (c == 1)
end function is_prime
Could be optimezed by leaving the loop when c == 1 and i < n(after adding 1 to c)...
See on online fortran compiler
version with exit loop
While I am not familiar with modern Fortran, it looks to me as if function is_prime(n) result(ispr) is not working.
In the do loop in that function, you want a loop that tests thus:
is n divisible by 2?
is n divisible by 3?
is n divisible by 4?
is n divisible by 5?
and so on.
But, what it is actually doing is asking these:
is 2 divisible by 2?
is 3 divisible by 2?
is 4 divisible by 2?
is 5 divisible by 2?
and so on.
As a result, your counter will always have a non-zero value, and your function will always return false.
But, that's not the only problem. From your results, it looks like your Fortran implementation does not automatically initialize variables. Suppose I have statements like the following:
integer :: b
print *,b
What will be the result?
Remember, the names of variables represent locations in the computer's memory. If a variable is not initialized, it's value will be what was in the memory location before your program started to run. This value will not be related to your program.
I have 2 suggestions to fix the 2nd problem:
Prior to do i = 2, 10000, 1, have another loop that sets each value in array.
Set a values of each array (i) inside your do i = 2, 10000, 1 loop. One way to do this is to set one value when (is_prime(i) .eqv. .true.) is true and a different value when it is false.

Fortran. do while with function checking the prime number [duplicate]

This question already has answers here:
Does Fortran preserve the value of internal variables through function and subroutine calls?
(3 answers)
Closed 2 years ago.
I'm recently studying Fortran, and trying to make a program to check the prime number. The function works fine without any loop. It can give 1 when the given number is a prime number and 0 otherwise. However, it doesn't work properly when it is used in do while loop. In the range of 2 ~ 10, it is supposed to give 1 (for 2), 1(for 2), 0(for 4), 1(for 5), 0(for 6), etc. But, it keeps showing only 0. I'm pretty new to programming, so I'm not sure what I'm missing. I know there are many answers related to prime numbers, but I don't see any issue like this.
** Function checking prime numbers **
module prime_function
contains
integer function isPrime(inp_num)
implicit none
integer :: inp_num
integer :: i = 1
integer :: temp1 = 0
do while (i < inp_num)
i = i + 1
if(mod(inp_num, i) == 0) then
exit
end if
end do
if(inp_num == i) then
temp1 = 1
else
temp1 = 0
end if
isPrime = temp1
end function
end module
program fortran_q
use prime_function
implicit none
integer :: ii, a
a = isPrime(10)
print *, "10 is prime number, so the return : ", a
a = isPrime(11)
print *, "11 is prime number, so the return : ", a
ii = 1
do while (ii < 10)
ii = ii + 1
print *, isPrime(ii)
end do
end program
** Results **
10 is prime number, so the return : 0
11 is prime number, so the return : 1
0
0
0
0
0
0
0
0
0
You have a classic issue for people new to Fortran. The initialization of i and temp0 implies the SAVE attribute. When you call isPrime for the first time the values are set to 1 and 0. On the next invocation, the values of i and temp0 are set to whatever their previous values were when isPrime was last executed. The belong program fixes the issue.
module prime_function
implicit none
private
public isprime
contains
function isPrime(inp_num) result(res)
integer res
integer, intent(in) :: inp_num
integer i, temp1
i = 1
temp1 = 0
do while (i < inp_num)
i = i + 1
if (mod(inp_num, i) == 0) exit
end do
res = 0
if (inp_num == i) res = 1
end function
end module
program fortran_q
use prime_function
implicit none
integer :: ii, a
a = isPrime(10)
print *, "10 is prime number, so the return : ", a
a = isPrime(11)
print *, "11 is prime number, so the return : ", a
ii = 1
do while (ii < 10)
ii = ii + 1
print *, isPrime(ii)
end do
end program

How to obtain the smallest figure out of five figures using OO Fortran

In what way can I get the smallest figure in a given five digit figure. E.g 23764. How do I get 2 being the smallest.
Taking the figure as a digit such as 456879, in order to obtain the smallest from the digit which is 4, I implemented the following
program findsmallestFigure
implicit none
integer:: figure
integer:: c,smallest,largest
smallest = 9
largest = 0
figure = 23456
do while(figure .GT. 0 )
c = MOD(figure,10)
largest = max(c,largest)
smallest = min(c,smallest)
figure = figure/10
end do
print *,'The smallest digit is',smallest
end
How do I achieve the same result using Object Oriented approach in Fortran ?
Create a module with a user-defined type that contains all the results, and the subroutines to fill in the values
module numstat
! Holds the statistics of a figure
type stat
integer :: smallest, largest, count
end type
! Constructor from a figure. Invoke by 'stat(1234)`
interface stat
module procedure :: calc_stat
end interface
contains
! Fill statistics type from a figure
function calc_stat(fig) result(s)
integer, intent(in) :: fig
type(stat) :: s
integer :: digit, f
! make a copy of the figure because intent(in) arguments
! are immutable (cannot change).
f = fig
s%smallest = 9
s%largest = 0
s%count = 0
do while(f > 0 )
s%count = s%count + 1
digit = mod(f, 10)
s%largest = max(s%largest, digit)
s%smallest = min(s%smallest, digit)
f = f/10
end do
end function
end module
Then use the module in the main program
program SONumstat
use numstat
implicit none
type(stat) :: s
integer :: figure
figure = 23456
s = stat(figure)
print *,'The number of digits is ', s%count
print *,'The smallest digit is ',s%smallest
print *,'The largest digit is ',s%largest
end program SONumstat

What does call sleep(1) mean in Fortran?

program democonstanta
implicit none
c constanta
integer, parameter :: MIN_VALUE = 0
integer, parameter :: MAX_VALUE = 100
c var declaration
integer :: i = MIN_VALUE
do while (i <=MAX_VALUE)
write(*,'(a14)') "Please wait... "
write(*,'(i3,a2)', advance='no') i, "%"
call sleep(1)
if (i .it. MAX_VALUE) then
call execute_command_line("clear")
end if
i = i + 1
end do
call execute_command_line("clear")
write(*,'(a3)') "End."
end program democonstanta
Reference: https://gcc.gnu.org/onlinedocs/gfortran/SLEEP.html
It simply sleeps (waits) for a given number of seconds. In your case - one.