-bオプションに対応したcutコマンドを作成しました。
takk@deb9:~$ cat -n cut6.f
1 PROGRAM MAIN
2 CHARACTER*100 LINE
3 INTEGER DISP_LOC(100),N
4 CHARACTER*100 ARGS
5
6 N = IARGC()
7 DO 300 I=1,N
8 CALL GETARG(I,ARGS)
9
10 IF(ARGS(1:2).EQ.'-b') THEN
11 CALL B_OPT(ARGS(3:),DISP_LOC)
12 ELSE
13 OPEN(UNIT=10,FILE=ARGS(1:INDEX(ARGS,' ')-1),
14 1 STATUS='OLD',
15 2 ACCESS='SEQUENTIAL')
16 10 READ(10,*,END=100) LINE
17 CALL CUT(LINE,DISP_LOC)
18 GOTO 10
19 100 CLOSE(10,STATUS='KEEP')
20 END IF
21 300 CONTINUE
22 STOP
23 END
24
25 SUBROUTINE B_OPT(B_OPT_STRING,DISP_LOC)
26 CHARACTER*100 B_OPT_STRING
27 CHARACTER*100 SSTRING1(10),SSTRING2(10)
28 INTEGER I,SSIZE1,SSIZE2,K,L,M
29 INTEGER DISP_LOC(100)
30
31 DO 10000 I=1,100
32 DISP_LOC(I) = 0
33 10000 CONTINUE
34
35 CALL SPLIT(B_OPT_STRING,',', SSTRING1,SSIZE1)
36 DO 10200 I=1,SSIZE1
37 CALL SPLIT(SSTRING1(I),'-', SSTRING2,SSIZE2)
38 IF(SSIZE2.EQ.1) THEN
39 READ(SSTRING1(I),*) L
40 DISP_LOC(L) = 1
41 ELSE
42 READ(SSTRING2(1),*) L
43 READ(SSTRING2(2),*) M
44 DO 10100 K=L,M
45 DISP_LOC(K) = 1
46 10100 CONTINUE
47 END IF
48 10200 CONTINUE
49 END
50
51 SUBROUTINE SPLIT(SRC,SEP,DEST,SPLIT_SIZE)
52 CHARACTER*100 SRC
53 CHARACTER*1 SEP
54 CHARACTER*100 DEST(10)
55 INTEGER IND,S1,S2,RSLT,SPLIT_SIZE
56 IND = 0
57 S2=-1
58 I = 1
59 20100 RSLT = INDEX(SRC(IND+1:),SEP)
60 IF(RSLT.NE.0) THEN
61 S1 = IND+1
62 IND = IND + RSLT
63 S2 = IND-1
64 DEST(I) = SRC(S1:S2)
65 I = I + 1
66 GOTO 20100
67 END IF
68 DEST(I) = SRC(S2+2:)
69 SPLIT_SIZE = I
70 RETURN
71 END
72
73 SUBROUTINE CUT(LINE,DISP_LOC)
74 INTEGER DISP_LOC(100)
75 CHARACTER*100 LINE
76 DO 30100 I=1,100
77 IF(DISP_LOC(I).EQ.1) THEN
78 WRITE(*,31000) LINE(I:I)
79 END IF
80 IF(LINE(I:I).EQ.' ') THEN
81 WRITE(*,*) ''
82 GOTO 30200
83 END IF
84 30100 CONTINUE
85 30200 RETURN
86 31000 FORMAT(A$)
87 END
takk@deb9:~$
73行目のCUT関数が、列抽出する関数です。100列分配列を確認して、1がはいっていたら、部分文字列の抽出をします。空白が出現したら、文字列の終端とみなして、改行するためにWRITE(*,*) ”を実行しています。
動くでしょうか。GDBを使ってみます。
takk@deb9:~$ gfortran -g -fdollar-ok cut6.f takk@deb9:~$ gdb a.out
パラメータを設定し、パラメータ数の取得関数前まで実行します。
(gdb) set args -b2-3,5 x00 (gdb) l 1 PROGRAM MAIN 2 CHARACTER*100 LINE 3 INTEGER DISP_LOC(100),N 4 CHARACTER*100 ARGS 5 6 N = IARGC() 7 DO 300 I=1,N 8 CALL GETARG(I,ARGS) 9 10 IF(ARGS(1:2).EQ.'-b') THEN (gdb) b 6 Breakpoint 1 at 0x147b: file cut6.f, line 6. (gdb) run Starting program: /home/takk/a.out -b2-3,5 x00 Breakpoint 1, MAIN__ () at cut6.f:6 6 N = IARGC() (gdb)
パラメータ数は2ですので、合ってます。
(gdb) n 7 DO 300 I=1,N (gdb) p N $1 = 2 (gdb)
1を設定する配列の位置も、-bで指定した通りとなっています。
(gdb) n 8 CALL GETARG(I,ARGS) (gdb) 10 IF(ARGS(1:2).EQ.'-b') THEN (gdb) 11 CALL B_OPT(ARGS(3:),DISP_LOC) (gdb) 7 DO 300 I=1,N (gdb) p DISP_LOC $2 = (0, 1, 1, 0, 1, 0, 0, ~ (gdb)
ファイルから読み込んだ文字列もOKです。
(gdb) n 8 CALL GETARG(I,ARGS) (gdb) 10 IF(ARGS(1:2).EQ.'-b') THEN (gdb) 15 2 ACCESS='SEQUENTIAL') (gdb) 16 10 READ(10,*,END=100) LINE (gdb) 17 CALL CUT(LINE,DISP_LOC) (gdb) p line $3 = '10010', ' ' <repeats 95 times> (gdb)
(gdb) n 000 18 GOTO 10 (gdb) 16 10 READ(10,*,END=100) LINE (gdb) 17 CALL CUT(LINE,DISP_LOC) (gdb) s cut (line=..., disp_loc=..., _line=100) at cut6.f:76 76 DO 30100 I=1,100 (gdb) n 77 IF(DISP_LOC(I).EQ.1) THEN (gdb) 80 IF(LINE(I:I).EQ.' ') THEN (gdb) 76 DO 30100 I=1,100 (gdb) 77 IF(DISP_LOC(I).EQ.1) THEN (gdb) 78 WRITE(*,31000) LINE(I:I) (gdb) 080 IF(LINE(I:I).EQ.' ') THEN (gdb)
実行結果を見てしまった方が早そうです。
takk@deb9:~$ ./a.out -b1,2,3,4 x00 1001 1011 1021 1031 1041 1051 1061 1071 1081 1091 takk@deb9:~$ ./a.out -b1-4 x00 1001 1011 1021 1031 1041 1051 1061 1071 1081 1091 takk@deb9:~$ ./a.out -b2-3,5 x00 000 010 020 030 040 050 060 070 080 090 takk@deb9:~$
上手く行きました。


コメント