Fortranにはシステムコマンドを実行するサブルーチン
"system"があるが、これは本当にシステムを実行するだけで、その結果を得ることはできない。
ファイルの存在は
access関数で判定できるが、ディレクトリの存在の判定はできないし、
lsコマンドの結果なども取得できない。
(ディレクトリの存在の判定に限って言えば、出力ディレクトリがあるかどうかを確認したいなら新規ファイルをそのディレクトリ内で開いてみてそのステータスを見るなどで対応できるし、サブルーチン
"system"で
"mkdir -p"を実行してディレクトリを作成することもできる)
というわけで
Cに出動していただく。
Cには
"popen"(ピーオープン)という、ファイルを開くような感覚でプロセスを開いてコマンドを実行し、その結果を文字列として受け取ったり、さらに別のプロセスに受け渡したりすることができる、なんとも便利な関数がある。どうして
Fortranには無いんですか?
詳細や具体例は参考リンクを参照していただくとして、今回はそれを
Fortranで受け取るプログラムを作ってみる。
popenに関するリンク
+
popen / programming memo
+
コンピューター:C言語講座:fork,exec,pipeについて
+
popen関数の挙動まとめ - ペンギンは空を飛ぶ
今回の目的はターミナル画面の幅を取得すること。
ターミナル画面の幅はシステムコマンド "tput cols" で文字数として取得できる(ちなみに高さ、つまり行数は "tput lines")。
まず
Cでこのコマンドを実行してその結果を文字配列に格納する関数:
fp = popen("tput cols", "r")
でシステムコマンド
"tput cols"を実行し、それを読み込む。
実行できなかった場合はステータス
*statに
1を入れて返す。
実行できた場合はその結果を文字配列
strに格納し、さらにその長さを取得して返す。
次にこれを受け取って幅を数字にして返すサブルーチン:
Cとのコンパイルリンクにおける作法については
こちらにも書かれているとおり、
・
Fortran側で
Cの関数を呼び出す際は関数名の末尾のアンダーバーを消すこと(なので
C側で関数名の末尾にアンダーバーを付けておく必要がある)
・引数はポインターで渡す
という点に留意する。
また文字列(文字変数の配列)の扱い方が
Cと
Fortranとで異なるので、それも気を付ける。
Cの文字変数の配列は末尾にNULL終端文字が付いており、これをそのまま
Fortran側で数値に変換しようとするとエラーとなる。
つまり上のコードで
などとするとエラーになるということ。
これを回避するため、予め
Cの側で文字変数の配列の大きさ
clを取得しておき、そこまでの部分だけを数値に変換する。
これをベースとして、
Cの関数が上手く実行できたかどうかを示す
cstatの値に応じて場合分けすればよい。
こんな感じで呼び出す。