高水準入出力ライブラリによるファイルの扱い

システム・プログラム

                                       電子・情報工学系
                                       新城 靖
                                       <yas@is.tsukuba.ac.jp>

このページは、次の URL にあります。
http://www.hlla.is.tsukuba.ac.jp/~yas/coins/syspro-2000/2000-04-24 /file-lib.html
あるいは、次のページから手繰っていくこともできます。
http://www.hlla.is.tsukuba.ac.jp/~yas/coins/
http://www.is.tsukuba.ac.jp/~yas/index-j.html

■文字単位のフィルタ

----------------------------------------------------------------------
   1:	/*
   2:	        filter-char.c -- 文字単位の簡単なフィルタ
   3:	        ~yas/syspro1//file/filter-char.c
   4:	        $Header: /home/lab2/OS/yas/syspro1/file/RCS/filter-char.c,v 1.4 1998/04/27 16:41:23 yas Exp $
   5:	        Start: 1997/04/21 18:23:13
   6:	*/
   7:	
   8:	#include <stdio.h>      /* stdin, stdout, fopen(), fclose(), getc(), */
   9:	#include <ctype.h>      /* toupper() */
  10:	
  11:	extern void filter_char_upper( FILE *in, FILE *out );
  12:	
  13:	main( int argc, char *argv[] )
  14:	{
  15:	    int i ;
  16:	    FILE *fp ;
  17:	        if( argc == 1 )
  18:	            filter_char_upper( stdin, stdout );
  19:	        else
  20:	        {
  21:	            for( i=1 ; i< argc ; i++ )
  22:	            {
  23:	                if( (fp = fopen( argv[i],"r" )) == NULL )
  24:	                {
  25:	                    perror( argv[i] );
  26:	                    exit( -1 );
  27:	                }
  28:	                filter_char_upper( fp, stdout );
  29:	                fclose( fp );
  30:	            }
  31:	        }
  32:	}
  33:	
  34:	void filter_char_upper( FILE *in, FILE *out )
  35:	{
  36:	    int c ;     /* int型。char は、不可 */
  37:	        while( (c=getc(in)) != EOF )
  38:	        {
  39:	            putc( toupper(c),out );
  40:	        }
  41:	}
----------------------------------------------------------------------

実行例

----------------------------------------------------------------------
% ./filter-char [←]
abc[←]
ABC
asdfjkl;[←]
ASDFJKL;
^D
% []
----------------------------------------------------------------------

fopen()は、ファイルを開くライブラリ関数である。"r" は、 読み込み専用で ファイルを開くことを意味している。fopen()は、結果として FILE 構造体へ のポインタを返す。これは、stdio.h で宣言されている配列 _iob[] の要素へ のポインタである。これは、次のようなライブラリ関数で使われる。

    fgetc()           fputs()           getc()         getw()
    fgets()           fread()           ungetc()
    fprintf()         fscanf()
    fputc()           fwrite()          putc()         putc()
    fflush()          fseek()           ftell()
    frewind()         fclose()          fdopen()       freopen()
    ferrror()         feof()            clearerr()     fileno()

このような、struct FILE を使うライブラリ関数群は、次のような名前で呼ば れる。

putc() は、第1引数で指定された文字を第2引数で与えられたストリームへ 出力する。

fclose() は、ファイルを閉じるライブラリ関数である。

Java 風に書くとこうなる。

class FILE {
    int fgetc();
    int fputs(String str);
    size_t fread(byte buf, size_t size, size_t nmemb);
    ...
}

	FILE stdin ;
	FILE stdout ;
	int x = stdin.fgetc();
	stdout.fputs("hello");
引数の FILE *stream が、オブジェクトとなり、普通の引数からは消える。呼 出しの時には、オブジェクトを指定する。

■バッファと FILE 構造体

----------------------------------------------------------------------
   1:	/*
   2:	        filestruct-print.c -- _filestruct[] の内容を表示する
   3:	        ~yas/syspro1/file/filestruct-print.c
   4:	        $Header: /home/lab2/OS/yas/syspro1/file/RCS/filestruct-print.c,v 1.3 1998/04/27 16:59:12 yas Exp $
   5:	        Start: 1997/05/05 18:31:55
   6:	*/
   7:	
   8:	#include <stdio.h>
   9:	
  10:	#if     0
  11:	typedef struct {
  12:	    int                  _cnt;
  13:	    unsigned char       *_ptr;
  14:	    unsigned char       *_base;
  15:	    unsigned short       _flag;
  16:	    unsigned char        _flag;
  17:	    unsigned char        _file;
  18:	} FILE;
  19:	extern FILE             __iob[100 ];    
  20:	#endif
  21:	
  22:	extern void filestruct_print( FILE *fp );
  23:	
  24:	main()
  25:	{
  26:	    FILE *fp ;
  27:	
  28:	        printf("stdin  == 0x%x == &_iob[%d]\n",stdin, stdin-&__iob[0] );
  29:	        printf("stdout == 0x%x == &_iob[%d]\n",stdout, stdout-&__iob[0] );
  30:	        printf("stderr == 0x%x == &_iob[%d]\n",stderr, stderr-&__iob[0] );
  31:	
  32:	        fp = fopen("filestruct-print.c","r");
  33:	        printf("fp     == 0x%x == &__iob[%d]\n",fp, fp-&__iob[0] );
  34:	
  35:	        printf("fopen()\n");
  36:	        filestruct_print( fp );
  37:	        getc( fp );
  38:	        printf("getc()\n");
  39:	        filestruct_print( fp );
  40:	        getc( fp );
  41:	        printf("getc()\n");
  42:	        filestruct_print( fp );
  43:	        fclose( fp );
  44:	        printf("fclose()\n");
  45:	        filestruct_print( fp );
  46:	}
  47:	
  48:	
  49:	void filestruct_print( FILE *fp )
  50:	{
  51:	        printf("cnt:%d, ptr:0x%x, base:0x%x, flag:0%x, flag:%d, file:%d\n",
  52:	               fp->_cnt, fp->_ptr, fp->_base, fp->_flag,
  53:	               fp->_flag,fp->_file);
  54:	}
----------------------------------------------------------------------
#define getc(p)         (--(p)->_cnt < 0 ? __filbuf(p) : (int)*(p)->_ptr++)
----------------------------------------------------------------------
_cnt
バッファに入っている文字数
_ptr
バッファの先頭番地(次に読む文字)
_base
バッファ用に確保されているメモリ領域の先頭番地
_file
UNIXのファイル記述子
実行結果

----------------------------------------------------------------------
% make filestruct-print [←]
cc     filestruct-print.c   -o filestruct-print
% ./filestruct-print  [←]
stdin  == 0xfb4f044 == &_iob[0]
stdout == 0xfb4f054 == &_iob[1]
stderr == 0xfb4f064 == &_iob[2]
fp     == 0xfb4f074 == &__iob[3]
fopen()
cnt:0, ptr:0x0, base:0x0, flag:01, flag:1, file:3
getc()
cnt:1252, ptr:0x10002009, base:0x10002008, flag:09, flag:9, file:3
getc()
cnt:1251, ptr:0x1000200a, base:0x10002008, flag:09, flag:9, file:3
fclose()
cnt:0, ptr:0x0, base:0x0, flag:00, flag:0, file:3
% []
----------------------------------------------------------------------

■練習問題

★練習問題14 フィルタのプログラム

高水準入出力ライブラリ関数を持ちいて、次のようなフィルタを作りなさい。

文字単位のフィルタでは、getc(), fgetc(), getchar() と putc(), fputc(), putchar() などを使うとよい。行単位のフィルタでは、 fgets(), fputs(), fprintf() などを使うとよい。 (gets(), fscanf(), scanf() は、セキュリティ・ホールになりやすいので、使 わない。)


↑[もどる] ←[4月17日] ・[4月24日] →[5月01日] [課題]
Last updated: 2000/04/23 01:30:01
Yasushi Shinjo / <yas@is.tsukuba.ac.jp>