FORTRAN(catコマンドを作るその3)

旧2-5. Fortran毎日学習

FORTRANで作ったcatコマンドに-nオプションをつけます。

takk@deb9:~$ cat cat3.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
        WRITE(*,*) LINE
        GOTO 10
  100 CLOSE(10,STATUS='KEEP')
11111 CONTINUE
      STOP
      END

takk@deb9:~$

前回のこのプログラムのバッファサイズを100から50ぐらいにして、ターミナルで改行されず表示できるように修正しておきます。

      CHARACTER*50 ARGS,LINE

行番号を表示するために必要な変数は、行番号そのものを格納する変数と、
オプションの状態を格納するフラグ、ぐらいでしょうか。
それぞれNUMとNFLAGと名付けました。

      INTEGER N,NFLAG,NUM

-nが指定されたかどうかの判定は、先頭パラメータが’-n’の場合としましょう。

      IF((I.EQ.1).AND.(ARGS.EQ.'-n')) 

あとは行番号表示ですが、WRITEの引数を増やすだけです。

      WRITE(*,*) NUM,LINE

修正したプログラムです。

takk@deb9:~$ cat cat4.f
      PROGRAM cat
      CHARACTER*50 ARGS,LINE
      INTEGER N,NFLAG,NUM
      NFLAG=0
      N = IARGC()
      DO 11111 I=1,N
        CALL GETARG(I,ARGS)
        IF((I.EQ.1).AND.(ARGS.EQ.'-n')) THEN
          NFLAG=1
        ELSE
          NUM=1
          OPEN(UNIT=10,FILE=ARGS(1:INDEX(ARGS,' ')-1),
     1    STATUS='OLD',
     2    ACCESS='SEQUENTIAL')
   10     READ(10,*,END=100) LINE
          NUM=NUM+1
          IF(NFLAG.EQ.1) THEN
            WRITE(*,*) NUM,LINE
          ELSE
            WRITE(*,*) LINE
          END IF
          GOTO 10
  100     CLOSE(10,STATUS='KEEP')
      EN  D IF
11111 CONTINUE
      STOP
      END

takk@deb9:~$

実行してみます。

takk@deb9:~$ ./a.out -n x00
           2 10
           3 20
           4 30
           5 40
           6 50
           7 60
           8 70
           9 80
          10 90
          11 100
takk@deb9:~$

おっと。カウントの位置を間違えました。WRITEの後じゃないといけませんね。

takk@deb9:~$ gfortran cat4.f
takk@deb9:~$ ./a.out -n x00
           1 10
           2 20
           3 30
           4 40
           5 50
           6 60
           7 70
           8 80
           9 90
          10 100
takk@deb9:~$

本物のcatと桁数を合わせたいので、cat -nを確認します。

takk@deb9:~$ cat -n x00
     1  10
     2  20
     3  30
     4  40
     5  50
     6  60
     7  70
     8  80
     9  90
    10  100
takk@deb9:~$

行番号は6桁ですね。区切り文字も空白なのかタブなのか確認しましょう。

takk@deb9:~$ cat -n x00 | od -tx1 -An -w10
 20 20 20 20 20 31 09 31 30 0a
 20 20 20 20 20 32 09 32 30 0a
 20 20 20 20 20 33 09 33 30 0a
 20 20 20 20 20 34 09 34 30 0a
 20 20 20 20 20 35 09 35 30 0a
 20 20 20 20 20 36 09 36 30 0a
 20 20 20 20 20 37 09 37 30 0a
 20 20 20 20 20 38 09 38 30 0a
 20 20 20 20 20 39 09 39 30 0a
 20 20 20 20 31 30 09 31 30 30
 0a
takk@deb9:~$

タブですね。では、cat -nの書式に合わせて、FORTRANのプログラムも改造してみます。
修正後のプログラムです。

takk@deb9:~$ cat cat4.f
      PROGRAM cat
      CHARACTER*50 ARGS,LINE
      INTEGER N,NFLAG,NUM
      NFLAG=0
      N = IARGC()
      DO 11111 I=1,N
        CALL GETARG(I,ARGS)
        IF((I.EQ.1).AND.(ARGS.EQ.'-n')) THEN
          NFLAG=1
        ELSE
          NUM=1
          OPEN(UNIT=10,FILE=ARGS(1:INDEX(ARGS,' ')-1),
     1    STATUS='OLD',
     2    ACCESS='SEQUENTIAL')
   10     READ(10,*,END=100) LINE
          IF(NFLAG.EQ.1) THEN
            WRITE(*,22222) NUM,LINE
          ELSE
            WRITE(*,33333) LINE
          END IF
          NUM=NUM+1
          GOTO 10
  100     CLOSE(10,STATUS='KEEP')
        END IF
11111 CONTINUE
22222 FORMAT(I6,'       ',A)
33333 FORMAT(A)
      STOP
      END

takk@deb9:~$

実行結果です。

takk@deb9:~$ gfortran cat4.f
takk@deb9:~$ ./a.out
takk@deb9:~$ ./a.out x00
10
20
30
40
50
60
70
80
90
100
takk@deb9:~$ ./a.out -n x00
     1  10
     2  20
     3  30
     4  40
     5  50
     6  60
     7  70
     8  80
     9  90
    10  100
takk@deb9:~$

コメント

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