READ (*,*)
的作用是从标准输入读取数据,例如通过键盘输入的字符。
正如问题所示,COMMAND_ARGUMENT_COUNT()
可以用来获取命令行参数的数量。
High Performance Mark 给出的答案展示了如何使用 GET_COMMAND_ARGUMENT()
将由空格分隔的单个命令行参数检索为单个字符字符串。您还可以使用 GET_COMMAND()
获取整个命令行。然后,您需要将基于字符的信息解析为程序中的数据。
在非常简单的情况下,您只需要程序需要的两个数字,因此您可以从 arg 1 读取一个数字,从 arg 2 读取另一个数字。这很简单。或者,如果它们是逗号分隔的,您可以从单个参数中读取三个数字,例如 1,2,3
,使用简单的 read(arg,*) nums(1:3)
。
对于一般复杂的命令行解析,人们使用诸如 Hani 答案中提到的库。您需要设置它们,以便库知道命令行参数的预期语法和应该填充值的数据。
有一个折中的方法,它仍然相对简单,但已经有多个参数,对应于程序中的Fortran变量,可能存在也可能不存在。在这种情况下,可以使用名称列表来进行语法和解析。
以下是一个示例,关键点是名称列表/cmd/名称、点、标志
:
implicit none
real :: point(3)
logical :: flag
character(256) :: name
character(1024) :: command_line
call read_command_line
call parse_command_line
print *, point
print *, "'",trim(name),"'"
print *, flag
contains
subroutine read_command_line
integer :: exenamelength
integer :: io, io2
command_line = ""
call get_command(command = command_line,status = io)
if (io==0) then
call get_command_argument(0,length = exenamelength,status = io2)
if (io2==0) then
command_line = "&cmd "//adjustl(trim(command_line(exenamelength+1:)))//" /"
else
command_line = "&cmd "//adjustl(trim(command_line))//" /"
end if
else
write(*,*) io,"Error getting command line."
end if
end subroutine
subroutine parse_command_line
character(256) :: msg
namelist /cmd/ name, point, flag
integer :: io
if (len_trim(command_line)>0) then
msg = ''
read(command_line,nml = cmd,iostat = io,iomsg = msg)
if (io/=0) then
error stop "Error parsing the command line or cmd.conf " // msg
end if
end if
end subroutine
end
在Bash中的用法:
> ./command flag=T name=\"data.txt\" point=1.0,2.0,3.0
1.00000000 2.00000000 3.00000000
'data.txt'
T
或者
> ./command flag=T name='"data.txt"' point=1.0,2.0,3.0
1.00000000 2.00000000 3.00000000
'data.txt'
T
对于字符串中的引号进行转义是不幸必要的,因为bash会吃掉第一个引号。
./a.out | echo '3.1d0 1.d0'
,但它没有起作用。对于我的目的来说,这种方式更好,因为不需要指定格式,这似乎更自然和通用! - Debanjan Basu