FORTRAN(revコマンドを作る)

旧2-5. Fortran毎日学習

FORTRANです。
今回はまったく作れる気がしないrevコマンドを作ろうかと思います。

revコマンドは、テキストを左右逆にするコマンドです。使い方はこんな感じです。

takk@deb9:~$ seq 12345 12349 > x00
takk@deb9:~$ cat x00
12345
12346
12347
12348
12349
takk@deb9:~$ rev x00
54321
64321
74321
84321
94321
takk@deb9:~$

ではFORTRANのプログラムを作っていきます。いきなり左右逆は難しいので、ただそのまま表示するだけのサブルーチンREVを作ります。`

takk@deb9:~$ cat rev1.f
      PROGRAM cat
      CHARACTER*100 ARGS,LINE
      INTEGER N
      N = IARGC()
      DO 11111 I=1,N
        CALL GETARG(I,ARGS)
        OPEN(UNIT=10,FILE=ARGS(1:INDEX(ARGS,' ')-1),
     1  STATUS='OLD',
     2  ACCESS='SEQUENTIAL')
   10   READ(10,*,END=100) LINE
        CALL REV(LINE)
        GOTO 10
  100 CLOSE(10,STATUS='KEEP')
11111 CONTINUE
      STOP
      END

      SUBROUTINE REV(LINE)
        CHARACTER*50 LINE
        WRITE(*,33333) LINE
33333   FORMAT(A)
        RETURN
      END

takk@deb9:~$

実行すると、

takk@deb9:~$ ./a.out x00
12345
12346
12347
12348
12349
takk@deb9:~$

期待通り表示されました。

では文字列を左右逆に表示していきます。
文字列変数は、変数名(先頭:最後) で、部分抽出ができるのでそれを使うことにします。

      SUBROUTINE REV(LINE)
        CHARACTER*50 LINE
        WRITE(*,33333) LINE(5:5)
33333   FORMAT(A)
        RETURN
      END
takk@deb9:~$ ./a.out x00
5
6
7
8
9
takk@deb9:~$

普通に配列として1文字アクセスできないかなと思い、このようなプログラムも作ってみましたが、こちらはビルドエラーになりました。

      SUBROUTINE REV(LINE)
        CHARACTER*50 LINE
        WRITE(*,33333) LINE(5)
33333   FORMAT(A)
        RETURN
      END

1文字だけ抽出することで、文字列の最後の位置から逆順に表示していけばrevコマンドのできあがりです。

takk@deb9:~$ cat rev2.f
      PROGRAM cat
      CHARACTER*100 ARGS,LINE
      INTEGER N
      N = IARGC()
      DO 11111 I=1,N
        CALL GETARG(I,ARGS)
        OPEN(UNIT=10,FILE=ARGS(1:INDEX(ARGS,' ')-1),
     1  STATUS='OLD',
     2  ACCESS='SEQUENTIAL')
   10   READ(10,*,END=100) LINE
        CALL REV(LINE)
        GOTO 10
  100 CLOSE(10,STATUS='KEEP')
11111 CONTINUE
      STOP
      END

      SUBROUTINE REV(LINE)
        CHARACTER*100 LINE
        INTEGER SP_FLAG,LOC
        SP_FLAG=0
        DO 2222 I=1,10
          LOC=10-I+1
          IF(SP_FLAG.EQ.0) THEN
            IF(LINE(LOC:LOC).NE. ' ') THEN
              SP_FLAG=1
              GOTO 1111
            END IF
            GOTO 2222
          END IF
 1111    WRITE(*,33333) LINE(LOC:LOC)
 2222   CONTINUE
        WRITE(*,*) ''
        RETURN
33333   FORMAT(A$)
      END

takk@deb9:~$

結果です。

takk@deb9:~$ ./a.out x00
54321
64321
74321
84321
94321
takk@deb9:~$

コメント

タイトルとURLをコピーしました