システムコマンドの結果を受け取る
    Top > Fortran > Cとの相互利用
    システムコマンドの実行結果が欲しい
     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の値に応じて場合分けすればよい.  こんな感じで呼び出す.
    References
    popen / programming memo + https://www.aihara.co.jp/~junt/program/popen.html コンピューター:C言語講座:fork,exec,pipeについて + http://www.ncad.co.jp/~komata/c-kouza3.htm popen関数の挙動まとめ - ペンギンは空を飛ぶ + https://peng225.hatenablog.com/entry/2021/05/10/183314