Cプログラミング
 Computer >> コンピューター >  >> プログラミング >> Cプログラミング

C言語のFILEデータ型とは?オペーク型の正体と使い方を解説

FILEデータ型とは

C言語でファイルを扱う際には、FILE型のポインタを使用します。つまり、FILEはデータ型の一つです。この型は「オペーク型(不透明型:Opaque datatype)」と呼ばれるもので、内部の実装詳細が隠蔽されています。プログラマはFILEの内部構造を直接操作するのではなく、fopen()fgets()fclose()といった標準ライブラリ関数を通じて間接的にファイルを操作します。

FILEの具体的な定義は処理系(OSや標準ライブラリ)ごとに異なります。以下は、Ubuntuシステムで使用されているGNU Cライブラリ(glibc)におけるFILEの定義です。

UbuntuにおけるFILEの定義

struct _IO_FILE {
    int _flags; /* High-order word is _IO_MAGIC; rest is flags. */
    #define _IO_file_flags _flags
    /* The following pointers correspond to the C++ streambuf protocol. */
    /* Note: Tk uses the _IO_read_ptr and _IO_read_end fields directly. */
    char* _IO_read_ptr; /* Current read pointer */
    char* _IO_read_end; /* End of get area. */
    char* _IO_read_base; /* Start of putback+get area. */
    char* _IO_write_base; /* Start of put area. */
    char* _IO_write_ptr; /* Current put pointer. */
    char* _IO_write_end; /* End of put area. */
    char* _IO_buf_base; /* Start of reserve area. */
    char* _IO_buf_end; /* End of reserve area. */
    /* The following fields are used to support backing up and undo. */
    char *_IO_save_base; /* Pointer to start of non-current get area. */
    char *_IO_backup_base; /* Pointer to first valid character of backup area */
    char *_IO_save_end; /* Pointer to end of non-current get area. */
    struct _IO_marker *_markers;
    struct _IO_FILE *_chain;
    int _fileno;
    #if 0
        int _blksize;
    #else
        int _flags2;
    #endif
        _IO_off_t _old_offset; /* This used to be _offset but it's too small. */
    #define __HAVE_COLUMN /* temporary */
    /* 1+column number of pbase(); 0 is unknown. */
    unsigned short _cur_column;
    signed char _vtable_offset;
    char _shortbuf[1];
    /* char* _save_gptr; char* _save_egptr; */
    _IO_lock_t *_lock;
    #ifdef _IO_USE_OLD_IO_FILE
};
struct _IO_FILE_complete
{
    struct _IO_FILE _file;
    #endif
    #if defined _G_IO_IO_FILE_VERSION && _G_IO_IO_FILE_VERSION == 0x20001
    _IO_off64_t _offset;
    # if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T
    /* Wide character stream stuff. */
    struct _IO_codecvt *_codecvt;
    struct _IO_wide_data *_wide_data;
    struct _IO_FILE *_freeres_list;
    void *_freeres_buf;
    size_t _freeres_size;
    # else
        void *__pad1;
        void *__pad2;
        void *__pad3;
        void *__pad4;
        size_t __pad5;
    # endif
    int _mode;
    /* Make sure we don't get into trouble again. */
    char _unused2[15 * sizeof (int) - 4 * sizeof (void *) - sizeof (size_t)];
    #endif
};

FILEを使ったサンプルプログラム

次に、FILE型を使った実際のプログラム例を見てみましょう。この例では、テキストファイルを開き、fscanf()fgets()を使って内容を順に読み込んで表示します。

読み込むテキストファイル(/tmp/test.txt)の内容は以下のとおりです。

This
is testing for fprintf...
This is testing for fputs...

サンプルコード

#include <stdio.h>
int main() {
    FILE *fp;
    char buff[255];
    fp = fopen("/tmp/test.txt", "r");
    fscanf(fp, "%s", buff);
    printf("1 : %s\n", buff);
    fgets(buff, 255, (FILE*)fp);
    printf("2: %s\n", buff);
    fgets(buff, 255, (FILE*)fp);
    printf("3: %s\n", buff);
    fclose(fp);
    return 0;
}

実行結果

1 : This
2: is testing for fprintf...

3: This is testing for fputs...

fscanf()は空白文字で区切られた最初の単語("This")のみを読み込むのに対し、fgets()は改行までの1行全体を読み込む点に注目してください。この違いが、出力結果の差となって現れています。

まとめ

FILEは、ファイル操作の状態(読み書きポインタ、バッファ位置、ファイルディスクリプタなど)を管理するための構造体であり、その実装は標準ライブラリの内部に隠されています。開発者はFILE型のポインタを取得し、標準入出力関数に渡すだけでファイルの読み書きが行えます。この設計により、OSやライブラリの違いを意識せず、移植性の高いファイル操作コードを書くことが可能になっています。

  1. AIファイルとは?開き方から変換方法まで徹底解説

    この記事のポイントAIファイルは、Adobe Illustrator(アドビ イラストレーター)で作成されるベクター画像ファイルです。開くにはIllustratorを使用するか、無料のInkscapeなどを利用できます。Zamzarなどのオンラインツールや各種ソフトを使って、PNG・JPG・SVGなどの形式に変換できます。この記事では、AIファイルの概要から、実際に開く方法、SVG・JPG・PDF・PNGなど他の形式への変換方法まで、わかりやすく解説します。他のソフトウェアとの互換性を持たせたい場合にも役立つ内容です。AIファイルとは何か拡張子が「.ai」のファイルは、ほとんどの場合、Adob

  2. C言語の基本データ型を徹底解説!int・char・floatの種類とサイズ一覧

    C言語の基本データ型とは? C言語のコンパイラがサポートする基本データ型は、大きく分けて次の4つです。 整数型(Integer) 文字型(Character) 浮動小数点型(Floating-point) 倍精度浮動小数点型(Double precision floating point) プログラムで扱う値の種類(整数・文字・実数など)に応じて適切な型を選ぶことは、正確で効率的なコードを書くための第一歩です。なお、各データ型のサイズや表現できる値の範囲は、使用するコンパイラや実行環境によって異なる場合がある点に注意してください。 整数型(Integral Data Type) 整数型は