如何在Fortran中获取未知长度的命令行参数?

时间:2016-02-02 12:32:26

标签: arrays string fortran

我想从用于运行程序的命令行中读取一些文本字符串。我在程序中使用内部子例程GET_COMMAND_ARGUMENT基本上是这样的:

program test
character(len=100) :: argument
call GET_COMMAND_ARGUMENT(1,argument)
print*, argument
end program test

这里的问题是我觉得在编译时设置字符串的最大长度有点危险。一些参数通常是带有路径的文件,因此它们可能很长。将静态长度设置为1000的解决方案听起来像一个丑陋的解决方法。

在Fortran中是否有一种更优雅的方式来定义一个能够包含长度仅在运行时知道的字符串的字符串?

2 个答案:

答案 0 :(得分:5)

可以使用所谓的延迟长度字符变量。这些不是固定的固定长度,它们的使用可以在a related one about data input等问题中找到。

但是,即使使用了延迟长度变量(因为这是语法)

character(len=:), allocatable :: argument
allocate(character(some_length) :: argument)  ! For integer some_length
call GET_COMMAND_ARGUMENT(1,argument)
print*, argument
end

仍然需要担心some_length应该是什么。如果我们选择100,我们会回到原来的位置。

我们不得不担心这一点,因为get_command_argument没有采用这样的延迟长度参数并将其分配到所需的长度。那是

character(len=:), allocatable :: argument
call GET_COMMAND_ARGUMENT(1,argument)  ! Will argument be allocated in the subroutine?
print*, argument
end

提供答案" no"。

然后,为了处理这个问题,我们会查看get_command_argument的其他(可选)参数。特别是,有一个叫length

character(len=:), allocatable :: argument
integer arglen
call GET_COMMAND_ARGUMENT(1,length=arglen)
allocate(character(arglen) :: argument)
call GET_COMMAND_ARGUMENT(1,value=argument)
print*, argument
end

当然,可以创建一个包装器子例程,它确实采用了可分配的延迟长度字符变量,并完成了所有工作。

答案 1 :(得分:2)

我会留下这个完整性,这可能对某些人有用,但francescalus的回答要好得多。

基本上,只需阅读一些默认长度,检查STATUS变量,如果它不合适,请重试。

来自gcc手册:

  

如果参数检索失败,则STATUS为正数;如果是VALUE   包含截断的命令行参数,STATUS为-1;和   否则STATUS为零。

所以:

character(len=:), allocatable :: argument
integer :: stat, n

n = 100
allocate(character(n) :: argument)

do
  call GET_COMMAND_ARGUMENT(1,argument, status=stat)
  if (stat>=0) exit
  deallocate(argument)
  n = n * 2
  allocate(character(n) :: argument)
end do

if (stat>0) error...

argument = trim(argument)

print*, argument