Caution

お使いのブラウザはJavaScriptが実行できない状態になっております。
当サイトはWebプログラミングの情報サイトの為、
JavaScriptが実行できない環境では正しいコンテンツが提供出来ません。
JavaScriptが実行可能な状態でご閲覧頂くようお願い申し上げます。

  1. トップページ
  2. C言語辞典
  3. fseek() / ftell() / rewind() / feof()

fseek() / ftell() / rewind() / feof()

ファイルの読み書き位置(ファイル位置指示子)を移動・取得したり、末尾に達したかどうかを判定したりする関数です。ランダムアクセスが必要なファイル処理に使います。

構文
// ファイル位置を基準点からオフセット分移動します。
// 戻り値: 成功時は 0、失敗時は非0。
int fseek(FILE *stream, long offset, int whence);

// 現在のファイル位置をバイト数で返します。
// 戻り値: 現在位置、エラー時は -1L。
long ftell(FILE *stream);

// ファイル位置を先頭に戻します(エラーフラグもクリアします)。
void rewind(FILE *stream);

// ファイル末尾フラグが立っているか調べます。
// 戻り値: EOF に達していれば非0、そうでなければ 0。
int feof(FILE *stream);
whence(基準点)一覧
定数基準点概要
SEEK_SETファイル先頭先頭から offset バイト目に移動します。offset は 0 以上の値を指定します。
SEEK_CUR現在位置現在位置から offset バイト分前後に移動します。負の値で後退できます。
SEEK_ENDファイル末尾末尾から offset バイト分移動します。ファイルサイズを調べる際は offset に 0 を指定します。
サンプルコード
#include <stdio.h>
#include <stdlib.h>

int main(void) {
    // ファイルサイズを fseek + ftell で調べます。
    FILE *fp = fopen("lines.txt", "rb");
    if (fp == NULL) { perror("fopen"); return EXIT_FAILURE; }

    fseek(fp, 0, SEEK_END);     // 末尾に移動します。
    long file_size = ftell(fp); // 現在位置 = ファイルサイズ(バイト)です。
    printf("ファイルサイズ: %ld バイト\n", file_size);

    rewind(fp); // 先頭に戻します。
    printf("rewind後の位置: %ld\n", ftell(fp)); // 『0』と出力されます。

    // SEEK_SET で先頭から7バイト目に移動して読み込みます。
    fseek(fp, 7, SEEK_SET);
    char buf[64];
    if (fgets(buf, sizeof(buf), fp) != NULL) {
        printf("7バイト目から: %s", buf); // 2行目の内容が出力されます。
    }

    // feof でループ終了を確認します(推奨: 戻り値で判定する方が確実です)。
    rewind(fp);
    int ch;
    int count = 0;
    while ((ch = fgetc(fp)) != EOF) {
        count++;
    }
    if (feof(fp)) {
        printf("正常に末尾に達しました。文字数: %d\n", count);
    }

    fclose(fp);
    return 0;
}
概要

テキストモードで開いたファイルへの fseek() は、SEEK_SET + ftell() が返した値の組み合わせ以外では動作が処理系依存になります。ランダムアクセスが必要な場合は必ずバイナリモード(『"rb"』)で開いてください。

『feof()』はファイル末尾フラグを確認するだけです。『while (!feof(fp))』をループ条件にすると最後のデータを2回処理するバグが生じることがあります。かわりに『fgets()』や『fgetc()』の戻り値で EOF を判定するパターンを推奨します。

ファイルの読み書き関数全般については『fread() / fwrite()』および『fgets() / fputs()』も参照してください。

記事の間違いや著作権の侵害等ございましたらお手数ですがまでご連絡頂ければ幸いです。