ファイル入出力

ファイル入出力についてみていきます。


ファイル処理のながれ

ファイル入出力処理を行うためには次の手順でコーディングします。

  1. ファイルポインタの宣言
  2. ファイルのオープン
  3. ファイル入出力
  4. ファイルのクローズ

▲PageTop

ファイルポインタの宣言

ファイル操作を行うためにはファイル情報を示す変数が必要です。C言語ではファイル情報を格納するFILE型構造体を用意し、そのポインタ(ファイルポインタ)を利用します。ファイルポインタの宣言は次の通りです。

FILE *変数名;

▲PageTop

ファイルのオープンとクローズ

ファイル操作する為には、まず「fopen()」を使用してファイルをオープンし、取得したファイルポインタでファイルアクセスします。そしてファイル操作終了後は「fclose()」でファイルポインタを開放して終了です。


ファイルオープン

「fopen()」の書式は次の通りです。

FILE *fopen(const char *filename, const char *mode);
【引数】
filename:ファイル名
mode:ファイルの取扱い方法(下記モード一覧参照)
【戻り値】
成功時:オープンしたファイルのファイルポインタ
失敗時:NULL

モード(mode)一覧
記号 処理 ファイルが存在するとき ファイルが存在しないとき
r 読み込み そのファイルポインタを返します。(カーソル位置は先頭) エラー(EOFを返します。)
r+ 読み込み・書き込み そのファイルポインタを返します。(カーソル位置は先頭) エラー(EOFを返します。)
w 書き込み ファイルを初期化し、そのファイルポインタを返します。 新規作成し、そのファイルポインタを返します。
w+ 書き込み・読み込み ファイルを初期化し、そのファイルポインタを返します。 新規作成し、そのファイルポインタを返します。
a 追加書き込み そのファイルポインタを返します。(カーソル位置は終端) 新規作成し、そのファイルポインタを返します。
a+ 追加書き込み・読み込み そのファイルポインタを返します。(カーソル位置は終端) 新規作成し、そのファイルポインタを返します。

※テキストモードとバイナリモード

下記に示すように各OSにより改行コード(ASCIIコード)が異なっており、これに伴ってC言語ではファイルの読み書き時に自動で改行コードの変換を行っています。

例えば、ファイルの読み書き時に改行コード「10 13」(Windows)があれば「10 13」から「10」(UNIX)に変換します。

但し、文字コード以外もデータとして保存するバイナリファイルでは、この自動変換によりデータ破壊につながる恐れがあります。したがってUNIX以外でバイナリファイルを取り扱う時には改行コードの変換を行わない「バイナリモード」を使用してください。


バイナリモードにする場合は、上記モード一覧の記号に「b」を付加します。

テキストモード バイナリモード
r rb
r+ r+b または rb+
w wb
w+ w+b または wb+
a ab
a+ a+b または ab+

ファイルクローズ

「fclose()」の書式は次の通りです。

int fclose(FILE *fp);
【引数】
fp:クローズするファイルのファイルポインタ
【戻り値】
成功時:0
失敗時:EOF

▲PageTop

ファイル入力

C言語でファイル入力するには主にの関数を使用します。


関数一覧
関数名 書式 処理
fgetc() int fgetc(FILE *stream); 「*stream」で示されるストリーム※1から1文字を取得します。
fgets() char *fgets(char *s, int n, FILE *stream); 「*stream」で示されるストリームから「n-1」文字を取得し「\0」を付加して、その文字列の先頭アドレスを引数のchar型ポインタ(*str) に渡すと共に戻り値としても返します。
fscanf() int fscanf(FILE *fp, const char *format, ...); ファイルポインタ(*fp)で示されるファイルからの入力値を書式指定した文字列として取得します。第3引数以降は「const char *format」(書式指定文字列※2)の変換指定子の数だけ変数を指定します。

※1「ストリーム」とは「データの流れ」を表現する用語です。ファイル入力するには「fopen()」で取得したファイルポインタを指定します。

※2「書式指定文字列」とは変換指定子やエスケープシーケンス等を含む文字列の事で、これにより入力時や出力時の書式を指定します。詳しくは下記の「fscanf()」で使用される書式指定文字列を参照してください。


「fscanf()」で使用される書式指定文字列

「fscanf()」で使用される書式指定文字列は次の「変換指定子」で形成されています。変換指定子の仕様は次の通りです。


%変換指定子

変換指定子一覧
記号 意味
c, C 1文字
s, S 文字列
d 符号付整数(10進数)
i 符号付整数(先頭が0のとき8進数、0xのとき16進数、それ以外は10進数)
u 符号なし整数(10進数)
o 符号なし整数(8進数)
x, X 符号なし整数(16進数)
e, E 符号付浮動小数点([-]d.dddde[+/-]ddd形式)
f 符号付浮動小数点([-]dddd.dddd形式)
g, G 精度をしてします。これにより指定された精度以上のときはfの形式からeの形式で取得します。
p ポインタ
n 入力文字数
[・・・] ”・・・”に入る文字が入力されている間値を取り込みます。
[^・・・] ”・・・”に入る文字が入力されると値の取り込みを終了します。

次のように「変換指定子」にはオプションを使用することも出来ます。([ ]内は省略可能です。)

%[代入抑止][最大フィールド幅][型修飾子]変換指定子

オプション
[代入抑止] ”*”で指定された箇所は取り込みを行いません。
[最大フィールド幅] 取得する文字数を指定します。
[型修飾子] ”h”はshotの時、”l,L”はlongの時に指定します。

ファイル入力の使用例

・サンプルソース(sample1201.c)

#include <stdio.h>

int main(void) {
    FILE *fp;  /* ファイルポインタの宣言 */
    char s[256];
    char c;
    if ((fp = fopen("sample1201.txt", "r")) == NULL) {  /* ファイルのオープン */
        printf("file open error!!\n");
        return 1;
    }
    /* fetc()で取得 */
    printf("Read by fetc() ----------------------------------------\n");
    while((c = fgetc(fp)) != EOF){
        putchar(c);
    }
    printf("\n-------------------------------------------------------\n");
    fseek(fp, 0, SEEK_SET);
    /* fgets()で取得 */
    printf("Read by fgets() ----------------------------------------\n");
    while (fgets(s, 256, fp) != NULL) {
        printf("%s", s);
    }
    printf("\n-------------------------------------------------------\n");
    fseek(fp, 0, SEEK_SET);
    /* fscanf()で取得 */
    printf("Read by fscanf() --------------------------------------\n");
    while(fscanf( fp, "%s", s) != EOF){
        printf( "%s\n", s);
    }
    printf("-------------------------------------------------------\n");
    fclose(fp);  /* ファイルのクローズ */

    return 0;
}

・入力ファイル(sample1201.txt)

abc
def
あいうえお
123

・実行結果

C:\dev\c>sample1201 [Enter]
Read by fetc() ----------------------------------------
abc
def
あいうえお
123
-------------------------------------------------------
Read by fetc() ----------------------------------------
abc
def
あいうえお
123
-------------------------------------------------------
Read by fscanf() --------------------------------------
abc
def
あいうえお
123
-------------------------------------------------------
        

▲PageTop

ファイル出力

C言語でファイル出力するには主にの関数またはマクロを使用します。


関数一覧
関数名 書式 処理
fputc() int fputc(int c, FILE *stream); キャラクタ(ASCIIコード)cをストリーム※1に出力します。
fputs() int fputs(const char *s, FILE *stream); 文字列sをストリームに出力します。
fprintf() int fprintf(FILE *stream, const char *format,...); 書式指定文字列※2をストリームに出力します。
第2引数以降は出力元となる変数を変換指定子※2の数だけ指定します。

※1「ストリーム」とは入出力先の事でファイル出力するには「fopen()」で取得したファイルポインタを指定します。

※2「書式指定文字列」とは変換指定子やエスケープシーケンス等を含む文字列の事で、これにより入力時や出力時の書式を指定します。詳しくは下記の「fprintf()」で使用される書式指定文字列を参照してください。


「fprintf()」で使用される書式指定文字列

「fprintf()」で使用される書式指定文字列は次の「変換指定子」で形成されています。変換指定子の仕様は次の通りです。


%変換指定子

変換指定子一覧
記号 意味
c, C 1文字
s, S 文字列
d 符号付整数(10進数)
i 符号付整数(先頭が0のとき8進数、0xのとき16進数、それ以外は10進数)
u 符号なし整数(10進数)
o 符号なし整数(8進数)
x, X 符号なし整数(16進数)
e, E 符号付浮動小数点([-]d.dddde[+/-]ddd形式)
f 符号付浮動小数点([-]dddd.dddd形式)
g, G 精度をしてします。これにより指定された精度以上のときはfの形式からeの形式で取得します。
p ポインタ

次のように「変換指定子」にはオプションを使用することも出来ます。([ ]内は省略可能です。)

%[フラグ][最小フィールド幅][精度][型修飾子]変換指定子

オプション
[フラグ] 「+」:符号を付加を付加します。
「-」:左詰にします。
「空白」:先頭に空白を付加します。
「0」:最小フィールドまで0埋めします。
「#o」:8進表示(先頭に0を付加)します。
「#ox」:16進表示(先頭に0xを付加)します。
[最小フィールド幅] 10進数の整数または、「*」で出力の桁数を指定します。「*」を指定したときは第2引数で桁数を指定します。
[精度] 変換指定子が「%d」、「%i」、「%u」、「%o」、「%x」、「%X」のときは最小の桁数を表します。
変換指定子が「%f」、「%e」、「%E」のときは小数点以下の桁数を表します。
変換指定子が「%g」、「%G」のときは最大有効桁数を表します。
変換指定子が「%s」のときは出力される最大バイト数を表します。
[型装飾子] 「h」はshotの時、「l」,「L」はlongの時に指定します。

ファイル出力の使用例

・サンプルソース(sample1202.c)

#include <stdio.h>

int main(void) {
    FILE *fp;  /* ファイルポインタの宣言 */
    char s[256];
    char c;
    if ((fp = fopen("sample1202.txt", "w")) == NULL) {  /* ファイルのオープン */
        printf("file open error!!\n");
        return 1;
    }
    /* fputc()による出力 */
    fputc(0x41, fp);
    fputc(0x42, fp);
    fputc(0x43, fp);
    fputc(0x44, fp);
    fputc(0x45, fp);
    fputc(0xa, fp);
    /* fputs()による出力 */
    fputs("あいうえお\n", fp);
    /* fprintf()による出力 */
    fprintf(fp, "%d\n", 12345);
    fclose(fp);  /* ファイルのクローズ */

    return 0;
}

・実行結果(sample1202.txt)

ABCDE
あいうえお
12345
        

▲PageTop