Fortran でプログラム書くときにいつも悩むのはデータの入力をどうするかということ。配列の要素数は可変にしておきたいし、パラメータの増減に柔軟に対応したい、できればタグ付けしたデータを順序に依存しないで読みたい。
となると、自前のパーサを Fortran で頑張って書くか、プリプロセッサを用意するか、C とリンクするか…
そんなとき Fortran で JSON を取り扱うモジュールを見つけたので紹介します。ただし Fortran 2008 以上限定。今や GCC でも 4.9 なら Fortran 2008 に対応 (すべてとは言ってない) してるので問題ないよね?
で、Fortran で JSON 形式のデータを取り扱う Cool なモジュールはこれ。その名も json-fortran。直球だな。
https://github.com/jacobwilliams/json-fortran
使い方は上記のリンクに src/json_module.f90 というファイルがあるのでリンクする。これだけ。付属ドキュメントには CMake を使ったライブラリ化の手順が書いてあるけれど、別にライブラリにしなくても使える。
使用例はご覧のとおり。
program main
use, intrinsic :: iso_fortran_env, wp => real64
use json_module
implicit none
character(len=256) :: prog, file
type(json_file) :: json
character(len=:), allocatable :: error_msg
logical :: status_ok, found
integer :: scalar_int
real(wp), allocatable :: array_real(:)
if (command_argument_count() /= 1) then
call get_command(prog)
write(error_unit, '("usage: ",a, " file")') trim(prog)
call exit(64) ! EX_USAGE
end if
call get_command_argument(1, file)
call json_initialize() ! json_module の初期化
call json%load_file(file) ! JSON ファイルの読み込み
if (json_failed()) then
call json_check_for_errors(status_ok, error_msg)
write(error_unit, '(a)') error_msg
call exit(65) ! EX_DATAERR
end if
! JSON ファイルからデータを読む
call json%get('sample.data(2).int_value', scalar_int, found)
call json%get('sample.array_of_real', array_real, found)
call json%destroy() ! clean up
write(output_unit, '("sample.data(2).int_value = ",g0)') scalar_int
write(output_unit, '("sample.array_of_real = ",/,*(4(f10.3),/))') array_real(:)
call exit(0) ! EX_OK
end program main
{
"sample": {
"data": [
{ "ID": "1" },
{
"ID": "2",
"int_value": 5
},
{ "ID": "3" }
],
"array_of_real": [
0.16, 80.05, 49.58, 77.29, 25.34, 15.28,
77.23, 64.69, 87.58, 26.94, 53.08, 0.8
]
}
}
F:\> gfortran -o sample json_module.f90 sample.f90
F:\> sample.exe data.json
sample.data(2).int_value = 5
sample.array_of_real =
0.160 80.050 49.580 77.290
25.340 15.280 77.230 64.690
87.580 26.940 53.080 0.800
F:\>
簡単だね。もちろん JSON 形式で出力することもできる。
大量のデータを扱うとどうなるのだろうとか不安要素がないわけでもないけれど、Fortran の弱点をフォローできる非常に便利なモジュールなんではないかな。