fgetc(),fputc()の悲劇ーー解決編2015年02月01日 21:48

前回紹介した、fputc(6,c)とputc(c),fgetc(5,c)とgetc(c)が交互に呼ばれると悲劇が起きます。 この原因はどこにあるでしょうか。

fputc(),putc()は、文字を書き出す前に、一行分の文字をため込みます。この書き出しバッファーは、 fputc()とputc()でそれぞれ独立しています。そのため、出力が分かれてしまい、別々に書き出されてしまいます。

fgetc(5,c),getc(c)も同様で、読み出しバッファーが独立しているため、読み出し順序が入力元の順書と違ってしまいます。

これを解決する、もっとも簡単な方法は、putc()はfputc()を呼び出して実現し、getc()はfgetc()を呼び出して実現することです。

新しいgetc(),putc()は以下の通り。

c getc3.for -- (extended version) get character from standard input
      integer*1 function getc(c)
      integer*1 c
      integer*1 fgetc

      getc = fgetc(5,c)
      return
      end
c putc4.for (extended version 2)-- put sharacter on standard output
      subroutine putc(c)
      integer*1 c

      call fputc(6,c)
      return
      end

fgetc(),fputc()のサンプル2015年02月08日 09:43

fgetc(),fputc()のサンプルを示します。

まずは、typex.for。テキストファイルをタイプアウトするプログラムです。

c typex.for -- type out test file
      program typex
      integer*1 c, fname(256)
      integer*1 fgetc
      integer fopen, getarg
      integer fin

      call initfile()

      if (getarg(1,fname,256) .eq. -1) then
          call error('USAGE: typex filename.')
      end if

      if (fopen(fin,fname,82) .eq. -1) then
          call error('file not found.')
      end if

      while (fgetc(fin,c) .ne. -1) do
          call putc(c)
      end while

      call fclose(fin)

      stop
      end
initfile()でファイルルーチンを初期化してから、fopen()します。

次は、filecopy.forです。ファイルをコピーするプログラムです。

c copyfile.for -- copy file
      program copyfile
      integer*1 c, finame(256), foname(256)
      integer*1 fgetc
      integer fopen, getarg
      integer fin, fout, junk

      call initfile()

      if (getarg(1,finame,256) .eq. -1) then ! EOF(-1)
          call error('USAGE: copoyfile source distination.')
      else if (getarg(2,foname,256) .eq. -1) then ! EOF(-1)
          call error('USAGE: copoyfile source distination.')
      end if

      if (fopen(fin,finame,82) .eq. -1) then ! LETR(82) EOF(-1)
          call error('source file not found.')
      end if

      junk = fopen(fout,foname,87)      ! LETW(87)

      while (fgetc(fin,c) .ne. -1) do   ! EOF(-1)
          call fputc(fout,c)
      end while

      call fclose(fin)
      call fclose(fout)

      stop
      end

ファイル関連のサブプログラムの使い方を紹介しました。