導入:なぜLEN=が重要なのか
数値計算の現場では、ログの出力、ファイルパスの生成、設定ファイルの読み込みなど、文字列を扱う機会が多々あります。Fortranにおいて、引数として受け取る文字列の長さを固定値(例:character(len=256))で定義してしまうと、呼び出し側でそれより長い文字列を渡した際に切り捨てが発生したり、逆に短い場合に無駄なスペースが混入したりするリスクがあります。LEN=を使用することで、呼び出し側の文字列長を自動的に検出し、バッファオーバーフローを論理的に防ぎつつ、メモリを効率的に扱うことが可能になります。
基礎知識:LEN=とは何か
Fortranにおいて、サブルーチンや関数の引数として文字列を定義する際、長さの指定部分にアスタリスク()を記述することを「仮引数の長さ継承(Assumed-length character dummy argument)」と呼びます。これにより、コンパイラは呼び出し側の実引数の長さを自動的に認識します。これは、C言語のポインタと長さのペアを渡す仕組みに似ていますが、Fortranでは言語仕様として安全かつ簡潔に実現されています。
実装:LEN=の使い方
実装は非常にシンプルです。サブルーチンの引数定義で character(len=) を指定するだけです。内部では、len(s) という組み込み関数を呼ぶことで、実行時に受け取った文字列の正確な長さを取得できます。これにより、動的なメモリ確保や、文字列の末尾までを正確に処理するロジックを安全に構築できます。
サンプルプログラム:安全な文字列処理
以下に、受け取った文字列を加工して出力する汎用的なサブルーチンの例を示します。
program test_len_star
implicit none
character(len=10) :: short_str = “Short”
character(len=30) :: long_str = “This is a very long string”
! 文字列長が異なっても同じサブルーチンで安全に処理可能
call print_str_info(short_str)
call print_str_info(long_str)
contains
subroutine print_str_info(s)
! LEN= を使用して呼び出し側の長さを継承する
character(len=), intent(in) :: s
integer :: n
! len(s) で受け取った文字列の長さを取得できる
n = len(s)
! trim() を使用して余計な空白を除去しつつ、正確に長さを表示
print , “文字列: “, trim(s), ” | 長さ: “, n
end subroutine print_str_info
end program test_len_star
応用・注意点:現場で陥りやすい罠
1. intent(out)での注意点:
intent(out) で LEN= を使用する場合、呼び出し側で割り当てられた長さを超えて書き込むことはできません。常に呼び出し側のサイズが上限となるため、受け取り側で十分なバッファを確保していると過信しないように注意してください。
2. サブルーチン間での受け渡し:
LEN= で受け取った変数を別のサブルーチンへさらに渡す場合も、同様に LEN= を引き継ぐ必要があります。もし中間で固定長に代入してしまうと、そこで切り捨てが発生する可能性があるため、最後まで LEN= で繋ぐのがベストプラクティスです。
3. トリミングの重要性:
Fortranの文字列は固定長であるため、短い文字列を長い変数に代入すると末尾に空白が入ります。ログ出力やファイル操作を行う際は、必ず trim() 関数や調整関数を使用して空白を除去する癖をつけておくと、バグを大幅に減らせます。

コメント