2013-11-21 138 views
3

我不能說這個免費的Fortran程序有什麼問題。它沒有正確處理它的命令行參數。這個Fortran程序有什麼問題?

它適用於如果我使用靜態數組作爲命令行參數而不是allocatable數組。

另外,這是一個很好的第一個Fortran程序嗎?這是Fortran有用的問題類型嗎?我已經知道了C,C++,和D

此行

character, allocatable :: argumen(:) 

module fibonacci 
    use ISO_FORTRAN_ENV 
    implicit none 
contains 
    subroutine output_fibonacci(ordinal) 
    ! Declare variables 
    integer, parameter :: LongInt = selected_int_kind (38) 
    integer, intent(in) :: ordinal 
    integer :: count 
    ! integer (kind=LongInt) :: count, compare=2 
    integer (kind=LongInt), dimension(2,2) :: matrix, initial 
    matrix=reshape((/ 1, 1, 1, 0 /), shape(matrix)) 
    initial=reshape((/ 1, 0, 0, 1 /), shape(initial)) 
    count = ordinal 
    ! Do actual computations 
    do while (count > 0) 
     ! If the exponent is odd, then the output matrix 
     ! should be multiplied by the current base 
     if (mod(count,2) == 1) then 
      initial = matmul(matrix, initial) 
     end if 
     ! This is the squaring step 
     matrix = matmul(matrix, matrix) 
     count = count/2 
    end do 
    write (*,*) initial(1,2) 
    end subroutine output_fibonacci 
end module fibonacci 
program main 
    use, intrinsic :: ISO_FORTRAN_ENV 
    use fibonacci 
    implicit none 
    ! The maximum allowed input to the program 
    integer :: max=200, i, size=20 
    character, allocatable :: argumen(:) 
    integer :: error, length, input 
    allocate(argumen(size)) 

    ! write(*,*) argcount 
    do i=1, command_argument_count() 
    call get_command_argument(i, argumen, length, error) 
    read(argumen,*,iostat=error) input 
    ! write(*,*) argument 
    ! write (*,*) input 
    if (error .ne. 0) then 
     write(ERROR_UNIT,'(I36.1,A)') input, "is not an integer" 
     stop (1) 
    else if (input > max) then 
     write(ERROR_UNIT,'(A,I36.1,A)') "Input ", input, " is too large" 
     stop (1) 
    end if 
    call output_fibonacci(input) 
    end do 
end program 

回答

8

有點聲明字符可分配數組。因此,聲明

allocate(argumen(size)) 

使argumen由20個單字符元素組成的數組。這不是在Fortran中處理字符串的常用方式,argumenget_command_argument的調用中的第二個參數的要求不匹配(類型或級別)。

相反,你應該寫

character(len=:), allocatable :: argumen 

申報argumen是分配長度的字符變量。在某些情況下,您可以簡單地分配給這樣的變量,例如

argumen = 'this is the argument' 

而不必事先明確地分配它。

使用英特爾Fortran v14時,get_command_argument的調用在沒有警告的情況下編譯,但在執行時參數argumen不會自動分配,並且它仍保持未分配狀態。我真的不確定這種行爲是否符合標準。一種方法是對get_command_argument進行兩次調用,首先獲取參數的大小,然後獲得參數;這樣

do i=1, command_argument_count() 
    call get_command_argument(i, length=length, status=error) 
    allocate(character(length)::argumen) 
    call get_command_argument(i, argumen, status=error) 
    ! do stuff with argument 
    deallocate(argumen) 
    end do 

使用名稱length的變量被分配在可選參數返回的值稱爲length是合法的,但蟎混亂。 deallocate語句確保argumen可以再次分配給下一個參數。

我會留給你說明和使用一個可分配數組的可分配長度字符的練習。

免責聲明:接下來的兩個段落包含一些可能會發現主觀的材料。我不會對這個答案的這些部分進行任何討論。

這是一個很好的第一個Fortran程序嗎?這比我在這裏看到的很多東西都要好。我個人比較喜歡統一使用現代/=.ne.<.lt),我不使用stop,如果我能避免它(我通常能),而且我相信我能找到其他尼特到挑。

這是Fortran有用的問題類型嗎? Fortran對所有類型的問題都很有用,但我承認使用它來編寫Web服務器可能頗具挑戰性。