Home > Enterprise >  Nested Do and Do while Fortran loops
Nested Do and Do while Fortran loops

Time:09-21

I'm writing this small program that stores grades in an array and then averages them. The program is supposed to accept up to 10 grades and stop and only accept grades that are > 0 and < 100. Here is my code:

  program Average
  implicit none 
  character(len = 50) f_name, l_name 
  integer i, j, amtOfGrades
  real grade, arraySum, avg
  
  Real, Dimension(10)::a
  
  do i = 1, 10
        if(.not. (j .LE. 100 .AND. j .GE. 0)) then
              write(*,*)'Enter grade: '
              read(*,*)a(i)
              j = a(i)
              arraySum = sum(a)
              avg = arraySum/10
        else
              avg = arraySum/(i-1)
        end if
  end do 

The problem I'm having is with the nested loop section. I cannot get the two conditions I need to work together, which are only up to 10 grades (what the DO is for) AND only accepting grades that in the range of 0-100 (what the DO WHILE is for).

CodePudding user response:

You need to issue an exit statement to quit the loop before the max of 10 grades is entered:

program Console1
use, intrinsic :: iso_fortran_env
implicit none

! Variables
integer, parameter :: maxcount = 10
real :: a(maxcount), ave
integer :: i, count
count = 0
do i = 1, maxcount
    write(*,*) 'Enter grade: '
    read(*,*) a(i)
    if( a(i)<=0.0 .or. a(i)>=100.0) then
        exit
    end if
    count = count   1
end do

ave = sum(a)/count
write(*,*) 'The average is: ', ave

end program Console1

If you look in help you will see

The EXIT statement causes execution of a DO loop or a named construct to be terminated.

CodePudding user response:

How to do this will depend on what you want to do if an input grade is not 0 <= grade <= 100. Does such an input count towards the limit of 10 grades?

If a bad input does count towards the limit, then you will only need to read from the user 10 times, but you might end up with less than 10 grades total. So you will need to keep track of how many grades have been entered.

Code for this might look like:

program average
  implicit none
  
  integer :: i, amtOfGrades
  real :: grade, arraySum, avg
  real, dimension(10) :: a
  
  amtOfGrades = 0
  do i=1,10
    write(*,*) 'Enter grade: '
    read(*,*) grade
    if (0<=grade .and. grade<=100) then
      amtOfGrades = amtOfGrades   1
      array(amtOfGrades) = grade
    endif
  end do
  
  arraySum = sum(a(:amtOfGrades))
  avg = arraySum/amtOfGrades
end program

If instead a bad input does not count towards the limit then you will always end up with 10 grades, but you might have to read from the user an infinite number of times.

Code for this might look like:

program average
  implicit none
  
  integer :: i
  real :: grade, arraySum, avg
  real, dimension(10) :: a
  
  do i=1,10
    do
      write(*,*) 'Enter grade: '
      read(*,*) grade
      if (0<=grade .and. grade<=100) then
        array(i) = grade
        exit
      endif
    enddo
  end do
  
  arraySum = sum(a)
  avg = arraySum/10
end program
  • Related