这个Fortran程序有什么问题?

时间:2013-11-21 05:05:06

标签: fortran command-line-arguments fortran90 fortran2003

我不知道这个自由形式的Fortran程序有什么问题。它无法正确处理其命令行参数。

如果我使用静态数组作为命令行参数而不是allocatable数组,它就可以工作。

另外,这是一个很好的第一个Fortran程序吗?这是Fortran有用的问题类型吗?我已经知道C,C ++和一点点D。

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

1 个答案:

答案 0 :(得分:8)

这一行

character, allocatable :: argumen(:)

声明一个可分配的字符数组。声明

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程序吗?它比我在SO上看到的很多东西要好。我个人更喜欢一致地使用现代/=.ne.<.lt etc ),我不使用{{ 1}}如果我可以避免它(我通常可以),我相信我可以找到其他的尼特来挑选。

这是Fortran有用的问题类型吗? Fortran对所有类型的问题都很有用,但我承认使用它来编写Web服务器非常具有挑战性。