从命令行参数

时间:2017-11-24 03:02:35

标签: arrays fortran

我知道在Fortran中我可以声明一个N个元素的数组,如果N之前被声明为parameter(并且被定义为某个值)。

另一方面,我知道我可以通过使用子例程get_command_arg来获取程序来接受来自命令行的参数。

我的问题是:

从命令行调用程序时,我可以以某种方式声明由命令给出的多个元素的数组吗?

我正在寻找命令行之类的东西:

./main -30 

其中main.f03的开头是:

integer, parameter :: N = get_command_arg(1)
real :: x(N) ...

我试图不将数组定义为可分配的。

2 个答案:

答案 0 :(得分:3)

在某些语言中,您可以从命令行初始化变量和命名常量(如chapel),但Fortran不是其中之一。

你说“我试图不将数组定义为可分配的。”但这就是问题所在。你只需要。没有其他办法。

您的代码

integer, parameter :: N = get_command_arg(1)

real :: x(N) ...
由于多种原因,

是非法的。

您不能将GET_COMMAND_ARGUMENT()放入常量表达式中,因为它不在允许的函数中。它不返回编译时常量值。并且必须在编译时设置parameter初始值设定项。

GET_COMMAND_ARGUMENT()是一个子程序,而不是一个函数。它可以返回更多的东西,不仅仅是值,还有长度和状态。它不纯粹,Fortran标准试图只使用纯函数。其他内容,如RANDOM_NUMBER(),是子程序。在你自己的课程中也是一种很好的风格。

Fortran中创建从一次运行更改为运行的数组的唯一方法是创建数组allocatablepointer。本地数组也有自动数组。

答案 1 :(得分:1)

你可以这样做,没有allocatables。您只需将大小(在将其转换为整数后)传递到子例程中。但实际上,我认为没有理由不将allocatables用于这样的事情。

program main

implicit none

integer :: n,arg_len,istat
character(len=100) :: arg

call get_command_argument(1,value=arg,status=istat)
if (istat/=0) error stop 'error: cannot read first arg'

read(arg,'(I100)',iostat=istat) n
if (istat/=0) error stop 'error: first arg not an integer'

call real_main(n)

contains

    subroutine real_main(n)
    integer,intent(in) :: n
    integer,dimension(n) :: ival
    ival = 1
    write(*,*) ival
    end subroutine real_main

end program main

使用示例:

> ./main 1
       1
> ./main 2
       1           1
> ./main 3
       1           1           1