compare -- ファイルの比較 ― 2015年03月01日 09:52
ファイルの入出力ができたので、ファイルを使った小さいプログラムの紹介をします。
まずは、compareです。
compare file1 file2
file1とfile2を比較して、違っていたら表示します。まずは、RATFOR版から、
# compare2.r4 -- compare two files for equality character arg1(MAXLINE), arg2(MAXLINE) character line1(MAXLINE), line2(MAXLINE) integer getarg, equal, fopen, getlin integer infil1, infil2, lineno, m1, m2 if (getarg(1, arg1, MAXLINE) == EOF | getarg(2, arg2, MAXLINE) == EOF) then call error('usage: compare file1 file2.') if (fopen(infil1, arg1, READ) == ERR) call cant(arg1) if (fopen(infil2, arg2, READ) == ERR) call cant(arg2) lineno = 0 repeat { m1 = getlin(line1, infil1) m2 = getlin(line2, infil2) if ((m1 == EOF) | (m2 == EOF)) break lineno = lineno + 1 if (equal(line1,line2) == NO) call difmsg(lineno,line1,line2) } if (m1 == EOF & m2 != EOF) call remark('eof on file 1.') else if (m1 != EOF & m2 == EOF) call remark('eof on file 2.') stop end
まずは、引数を検査し入力ファイルをオープンします。次に、それぞれ1行ずつ読み込みながら 、逐次、比較し差違があれば、出力します。Watcom Fortran77版は、下記の通り。
c compare2.for -- compare two files for equality program compare integer*1 arg1(82), arg2(82) ! MAXLINE(82) integer*1 line1(82), line2(82) ! MAXLINE(82) integer getarg, equal, fopen , getlin integer infil1, infil2, lineno, m1, m2 call initfile() if (getarg(1,arg1,82) .eq. -1) then ! MAXLINE(82) EOF(-1) call error('1:usage: compare2 file1 file2.') else if (getarg(2,arg2,82) .eq. -1) then ! MAXLINE(82) EOF(-1) call error('2:usage: compare2 file1 file2.') end if if (fopen(infil1,arg1,82) .ne. 1) then ! READ(82) YES(1) call cant(arg1) end if if (fopen(infil2,arg2,82) .ne. 1) then ! READ(82) YES(1) call cant(arg2) end if lineno = 0 loop m1 = getlin(line1,infil1) m2 = getlin(line2,infil2) if ((m1 .eq. -1) .or. (m2 .eq. -1)) then ! EOF(-1) exit end if lineno = lineno + 1 if (equal(line1,line2) .ne. 1) then ! YES(1) call difmsg(lineno,line1,line2) end if end loop if ((m1 .eq. -1) .and. (m2 .ne. -1)) then call remark('eof on file 1.') else if ((m1 .ne. -1) .and. (m2 .eq. -1)) then call remark('eof on file 2.') end if call fclose(infil1) call fclose(infil2) stop end
ファイルは、getlin()を使って行単位で、読み込みます。fgetc()を使って下記のようになります。
c getlin.for -- get line from infile integer function getlin(line,u) integer*1 line(*) integer u integer*1 c,fgetc integer col col = 1 while (fgetc(u,c) .ne. -1) do ! EOF(-1) line(col) = c col = col + 1 if (c .eq. 10) then ! NEWLINE(10) line(col) = -2 ! EOS(-2) getlin = col - 1 return end if end while getlin = -1 ! EOF(-1) return end
実際の比較は、equal()を使います。RATFOR版は下記の通り。
# equal.r4 -- compare str1 to str2; return YES if equal, NO if not integer function equal(str1,str2) character str1(ARB), str2(ARB) integer i for (i = 1; str1(i) == str2(i); i = i + 1) if (str1(i) .eq. EOS) { equal = YES return } equal = NO return end
Watcom Fortran77版は下記の通り。
c equal.for -- compare str1 to str2; return YES(1) if equal, NO(0) if not integer function equal(str1,str2) integer*1 str1(*),str2(*) integer i i = 1 while (str1(i) .eq. str2(i)) do if (str1(i) .eq. -2) then ! EOS(-2) equal = 1 ! YES(1) return end if i = i + 1 end while equal = 0 ! NO(0) return end
さて、差違のある行の打ち出しはdifmsg()を使います。RATFOR版は下記の通り。
# difmsg.r4 -- print line numbers and differing lines subroutine difmsg(lineno, line1, line2) integer lineno character line1(ARB), line2(ARB) call putdec(lineno, 5) call putc(NEWLINE) call putlin(line1, STDOUT) call putlin(line2, STDOUT) return end
Watcom Fortran77版は下記の通り。
c difmsg.for -- print line numbers and differing lines subroutine difmsg(lineno, line1, line2) integer lineno integer*1 line1(*), line2(*) ! ARB(*) ARB(*) call putdec(lineno, 5) call putc(10) ! NEWLINE(10) call putlin(line1, 6) ! STDOUT(6) call putlin(line2, 6) ! STDOUT(6) return end
行単位の出力は、putlin()を使います。これは、fputc()を使って、下記のようになります。
c putlin.for -- put lin to u subroutine putlin(lin,u) integer*1 lin(*) ! ARB(*) integer u,i i = 1 while (lin(i) .ne. -2) do ! EOS(-2) call fputc(u, lin(i)) i = i + 1 end while return end
最近のコメント