2016-02-02 21 views
5

私はプログラムを実行するために使用されるコマンドラインからいくつかのテキスト文字列を読みたいと思います。ここでの問題は、私はそれがコンパイル時に文字列の最大長を設定するには少し危険だと感じていることであるFortranで長さが不明なコマンドライン引数を取得する方法は?

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

:私は基本的にのようなものであるプログラムにおける内部サブルーチンGET_COMMAND_ARGUMENTを使用しています。引数の中には、通常、パスを持つファイルなので、非常に長いかもしれません。長さを静的に1000に設定する方法は、醜い回避策のように聞こえます。

長さが実行時にしかわからない文字列を含むことができる文字列をFortranで定義すると、より洗練された方法はありませんか?

答えて

4

それは延期長文字変数と呼ばれるものを使用することが可能です。これらは一定の固定長ではなく、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 

1はまだ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 

であることは "ノー" の答えを提供しています。

これを処理する方法として、他の(オプションの)引数をget_command_argumentにします。特に、1は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つは、割り当て可能繰延長文字変数を取りましたし、すべてが仕事をしたラッパーサブルーチンを作成することができます。

+0

あなたのアプローチははるかに良いです、どういうわけか私はこの議論を忘れました。 –

+0

おそらく、このアプローチは 'get_environment_variable'でも動作することに注目する価値があります。 – francescalus

+0

ありがとう、これは大きな助けとなり、確かに問題を解決します。なぜなら、より単純な 'allocate(argument(some_length)) 'の代わりに、むしろ複雑な' allocate(character(some_length):: argument) 'を必要とするからです。 – Onturenio

1

私はこれを完全にするために残しておきますが、それは誰かにとって有益かもしれませんが、フランセカスの答えははるかに優れています。

基本的には、いくつかのデフォルトの長さで読み込み、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 
関連する問題