一文字ずつ読み書き

ファイル処理3

fgets関数やfprintf関数は文字列を読み取り/書き込みをする関数でしたが、一文字ずつ処理する関数もあります。
fgetc関数はファイルから一文字を読み取ります。
fputc関数はファイルに一文字を書き込みます。

以下は、指定したテキストファイルを別名で保存するサンプルコードです。


#include <stdio.h>
#include <stdlib.h>

void Quit()
{
    printf("Enterキーで終了。\n");
    getchar();
    exit(0);
}

int main()
{
    const char *fileIn = "C:\\test.txt";		//読み取り先ファイル
    const char *fileOut = "C:\\test_Copy.txt";	//書き込み先ファイル

    printf("%sを%sにコピーしますか?\n", fileIn, fileOut);
    printf("y/n\n");

    int input = getchar();
    if(input != '\n')
        while (getchar() != '\n');

    if (input != 'y')
    {
        printf("キャンセルしました。\n");
        Quit();
    }

    FILE *fpIn, *fpOut;

    //fpIn = fopen(fileIn, "r");
    fopen_s(&fpIn, fileIn, "r");
    if (fpIn == NULL)
    {
        printf("%sのオープンに失敗しました。\n", fileIn);
        Quit();
    }

    //fpOut = fopen(fileOut, "w");
    fopen_s(&fpOut, fileOut, "w");
    if (fpOut == NULL)
    {
        printf("%sのオープンに失敗しました。\n", fileOut);
        fclose(fpIn); //先に開いていたファイルを閉じる
        Quit();
    }

    printf("\n%s\n- - - - -\n", fileIn);

	//一文字読み取る
    while ((input = fgetc(fpIn)) != EOF)
    {
        putchar(input);
		//一文字書き込む
        fputc(input, fpOut);
    }

    fclose(fpIn);
    fclose(fpOut);

    printf("\n- - - - -\n処理が終了しました。\n");

    getchar();
}

今回は読み取り側のファイルと書き込み側のファイルの二つを使用するので、ファイルを二つ同時に開きます。
それぞれオープンモードが異なることに注意してください。

Cドライブに適当な文字を入力した「test.txt」というファイルを配置した上でコードを実行してください。
場所を変える場合はコード上のファイルパスも変更してください。

少し長いコードですが、コピー処理をしているのは51行目からのループ文です。
それ以外はファイルのオープンや画面へのメッセージ表示などの処理です。

fgetc

fgetc関数はファイルから一文字を読み取ります。
(file get character。キャラクター=文字)

int fgetc(
 FILE *stream
);
ファイルストリームstreamから一文字読み取る。
戻り値は読み取られた値。
ファイルの終端、もしくはエラーを検出した場合はEOFを返す。

ファイルから一文字読み取るごとに読み取り位置はひとつずらされますから、これを繰り返すことで次々に文字を読み取ることができます。
ファイル終端に達するとEOFという定数を返すので、読み取りを終了します。
(EOF=End Of File)


int input;
while ((input = fgetc(fpIn)) != EOF)
{
	//何か処理
}

fputc関数

fputc関数はファイルに一文字を書き込みます。

int fputc(
 int c,
 FILE *stream
);
文字cをファイルストリームstreamに書き込む。
戻り値は書き込んだ文字。
エラーが発生した場合はEOFを返す。

読み込みが書き込みに変わっただけで、fgetc関数と使い方は同じです。

putchar関数

ついでの処理として、putchar関数でファイルに書き込まれる内容を画面に表示しています。

int putchar(
 int c
);
文字cを標準出力に出力する。
戻り値は書き込んだ文字。
エラーが発生した場合はEOFを返す。

getchar関数の逆の働きをする関数で、標準出力に一文字を出力する関数です。
printf関数を使用しても構いませんが、単に一文字を表示するだけならばこちらの方が簡潔に書けます。

ちなみにfputc関数の第二引数にstdoutを指定するとputchar関数と同じ動作になります。

exit関数

今回のサンプルコードではプログラムの終了条件が複数存在するので、どこからでも簡単に終了させるためにプログラム終了処理を関数化しています。
(4~9行目の関数Quit)
ここでexit関数というものが登場しています。

void exit(
 int status
);
終了コードstatusをシステムに返し、プログラムを終了する。

exit関数が呼び出されると、直ちにプログラムは終了します。
exit関数は<stdlib.h>に定義されているので、インクルード(#include)が必要です。

引数には終了コードを指定します。
正常終了ならば0を指定します。
0以外は異常終了を示す値となりますが、何を指定してもプログラムの動作自体は変わりません。
この値はプログラムを別のプログラム(親プロセス)から呼び出すときに、親プロセスに渡されます。
受け取った値をどのように処理するかは親プロセス次第です。