ファイルの書き込み

ファイル処理2

テキストファイルへの書き込みを行うにはfprintf関数を使用します。
以下のコードは、キーボードから文字列を受け取り、それを「C:\test.txt」に保存するサンプルです。


#include <stdio.h>
#include <string.h>

#define BUFFER 256

int main()
{
    printf("保存する文字列を入力してください\n");

    char output[BUFFER];
    fgets(output, BUFFER, stdin);

	//バッファのクリア
    if (output[strlen(output) - 1] != '\n')
        while (getchar() != '\n');

    FILE *fp;
    const char *file = "C:\\test.txt";

    //fp = fopen(file, "w");
    fopen_s(&fp, file, "w");

    if (fp == NULL)
    {
        printf("%sのオープンに失敗しました。\n", file);
        printf("Enterキーで終了。\n");
        getchar();
        return 0;
    }

    fprintf(fp, "%s", output);

    fclose(fp);

    printf("%sに保存しました\n", file);
    getchar();
}

キー入力の受け取り

ファイル書き込みの前に、キーボード入力の処理を説明します。
11行目ではキーボードから文字列を受け取るためにfgets関数を使用しています。
ファイルの読み込みの項でも説明しましたが、fgets関数は第一引数にstdinを指定することで、標準入力からキーボード入力を受け取ることができます。

fgets関数は改行までを読み取ることができますが、あらかじめ用意した配列(というか第二引数に指定するサイズ)よりも長い文字列が入力された場合、読み取れなかった文字列は標準入力のバッファに残ります。
バッファにデータが残ったままだと不具合が起きる可能性があるので、以下のコードで消去しておきます。


if (output[strlen(output) - 1] != '\n')
	while (getchar() != '\n');

このコードはstrlen関数を使用して、文字列配列から「NULL文字の手前の文字」を取り出します。
入力文字の長さが配列サイズに収まる場合、ここには改行文字が取得されているはずです。
改行文字以外の場合はバッファにデータが残っているので、getchar関数で改行文字が出現するまで文字を読み捨てています。

fprintf関数

受け取った文字列をテキストファイルに書き込む処理は単純です。

まず、fopen関数(fopen_s関数)の第三引数にwを指定し、ファイルを書き込みモードで開きます。
指定のファイルが存在しない場合には自動的に作成されます。

ファイルを書き込みモード(w)で開く場合、指定のファイルが既に存在するとそのファイルは上書きされてしまうので注意してください。

次に、開いたファイルに対してfprintf関数で書き込みを行います。

int fprintf(
 FILE *stream,
 const char *format [,
 argument ]...
);
ファイルストリームstreamに文字列formatを書き込む。
戻り値は書き込んだ文字数。
失敗した場合は負数を返す。

この関数はprintfと非常によく似ていて、使い方もほぼ同じです。
第一引数にファイルポインタを指定できるようになっていて、ここに指定したファイルに対して文字列の出力(書き込み)が可能です。

printf関数とほどんど同じですから、以下のように書式指定文字列(変換指定子)を使用することもできます。


//書式指定文字列を指定して書き込み
int kazu = 10;
fprintf(fp, "%d", kazu);

ちなみにfprintf関数の第一引数にstdoutを指定すると、printf関数と全く同じになります。


//標準出力(画面)に文字列を表示
fprintf(stdout, "あいうえお");

書き込みが終わったら、ファイル読み込みの場合と同じようにfclose関数でファイルをクローズして、プログラムは終了します。

printf関数に関して詳しくはprintf関数を参照してください。

fputs関数

ファイルへの書き込み関数にはfprintf関数のほかに、fputs関数というのもあります。
ファイルの読み取りにはfgets関数を使用しましたが、これと対になる関数です。

int fputs(
 const char *str,
 FILE *stream
);
文字列strをファイルストリームstreamに出力する。
戻り値は0以上の値。
関数が失敗した場合はEOFを返す。

#include <stdio.h>
#include <string.h>

#define BUFFER 256

int main()
{
    printf("保存する文字列を入力してください\n");

    char output[BUFFER];
    fgets(output, BUFFER, stdin);
    if (output[strlen(output) - 1] != '\n')
        while (getchar() != '\n');

    FILE *fp;
    const char *file = "C:\\test.txt";

    //fp = fopen(file, "w");
    fopen_s(&fp, file, "w");

    if (fp == NULL)
    {
        printf("%sのオープンに失敗しました。\n", file);
        printf("Enterキーで終了。\n");
        getchar();
        return 0;
    }

    fputs(output, fp);

    fclose(fp);

    printf("%sに保存しました\n", file);
    getchar();
}

29行目をfprintf関数からfputs関数に変更しただけです。

fputs関数とfprintf関数はどちらを使用しても構いませんが、fputs関数で書き込めるのは文字列のみです。
fprintf関数で書き込まれるのも文字列ですが、変換指定子により様々な型のデータをそのまま書き込むことができます。


FILE *fp;

//ファイルオープン等の処理
//...

char *str = "ABCDEFG";
int integer = 10;
double real = 3.141526535897;

//fprintfを使用して書き込み
fprintf(fp, "%s\n%d\n%.12f", str, integer, real);

//fputsを使用して書き込み
char output[30];
sprintf_s(output, 30, "%s\n%d\n%.12f", str, integer, real);
fputs(output, fp);

文字列を整形して書き込みたい場合や、数値を文字列として書き込みたい場合にはfprintf関数を使った方が便利です。