[C言語] ファイルを開いて中身を表示する方法を解説

C言語でファイルを開いて中身を表示するには、標準ライブラリのstdio.hを使用します。

まず、fopen関数を用いてファイルを開きます。開くモードとしては、読み込み専用の"r"を指定します。

次に、fgetcfgets関数を使ってファイルの内容を読み取ります。

読み取ったデータはprintf関数で表示できます。

最後に、fclose関数でファイルを閉じることを忘れないようにしましょう。

この記事でわかること
  • C言語でのファイルの開き方と閉じ方
  • ファイルの内容を行単位や文字単位で読み取る方法
  • ファイルの内容を表示するための関数の使い方
  • ファイル操作中のエラーハンドリングの方法
  • テキストファイルやバイナリファイルを扱う応用例

目次から探す

ファイルを開く方法

ファイルを操作するためには、まずファイルを開く必要があります。

C言語では、fopen関数を使用してファイルを開きます。

このセクションでは、fopen関数の使い方、ファイルモードの指定方法、そしてファイルが開けなかった場合の対処法について解説します。

fopen関数の使い方

fopen関数は、指定したファイルを開き、ファイルポインタを返します。

基本的な構文は以下の通りです。

#include <stdio.h>
FILE *filePointer;
filePointer = fopen("ファイル名", "モード");
  • ファイル名: 開きたいファイルの名前を指定します。
  • モード: ファイルをどのように開くかを指定します(例:読み込み専用、書き込み専用など)。

以下は、fopen関数を使ってファイルを開くサンプルコードです。

#include <stdio.h>
int main() {
    FILE *filePointer;
    filePointer = fopen("example.txt", "r"); // 読み込み専用でファイルを開く
    if (filePointer == NULL) {
        printf("ファイルを開けませんでした。\n");
        return 1;
    }
    // ファイル操作のコードをここに記述
    fclose(filePointer); // ファイルを閉じる
    return 0;
}

ファイルモードの指定

ファイルを開く際には、どのようにファイルを操作するかを指定する「モード」が必要です。

以下は、一般的なファイルモードの一覧です。

スクロールできます
モード説明
“r”読み込み専用で開く
“w”書き込み専用で開く
“a”追記モードで開く
“r+”読み書き両用で開く
“w+”読み書き両用で開く(新規)
“a+”読み書き両用で開く(追記)

ファイルが開けなかった場合の対処

fopen関数がファイルを開けなかった場合、NULLが返されます。

この場合、エラーメッセージを表示するなどの対処が必要です。

以下は、ファイルが開けなかった場合の対処方法を示すサンプルコードです。

#include <stdio.h>
int main() {
    FILE *filePointer;
    filePointer = fopen("nonexistent.txt", "r"); // 存在しないファイルを開こうとする
    if (filePointer == NULL) {
        perror("ファイルを開けませんでした"); // エラーメッセージを表示
        return 1;
    }
    // ファイル操作のコードをここに記述
    fclose(filePointer); // ファイルを閉じる
    return 0;
}

このコードでは、perror関数を使用して、エラーメッセージを標準エラー出力に表示しています。

これにより、なぜファイルが開けなかったのかをユーザーに知らせることができます。

ファイルの内容を読み取る

ファイルを開いた後は、その内容を読み取ることができます。

C言語では、ファイルの内容を読み取るためにいくつかの関数が用意されています。

このセクションでは、fgets関数による行単位の読み込み、fgetc関数による文字単位の読み込み、そしてfread関数によるバイナリデータの読み込みについて解説します。

fgets関数による行単位の読み込み

fgets関数は、ファイルから1行ずつ文字列を読み取るために使用されます。

以下は、fgets関数の基本的な使い方です。

#include <stdio.h>
int main() {
    FILE *filePointer;
    char buffer[256]; // 読み込んだ行を格納するバッファ
    filePointer = fopen("example.txt", "r");
    if (filePointer == NULL) {
        perror("ファイルを開けませんでした");
        return 1;
    }
    while (fgets(buffer, sizeof(buffer), filePointer) != NULL) {
        printf("%s", buffer); // 読み込んだ行を表示
    }
    fclose(filePointer);
    return 0;
}

このコードは、example.txtから1行ずつ読み込み、読み込んだ行を標準出力に表示します。

fgets関数は、指定したバッファサイズまでの文字列を読み込みます。

fgetc関数による文字単位の読み込み

fgetc関数は、ファイルから1文字ずつ読み取るために使用されます。

以下は、fgetc関数を使ったサンプルコードです。

#include <stdio.h>
int main() {
    FILE *filePointer;
    int ch; // 読み込んだ文字を格納する変数
    filePointer = fopen("example.txt", "r");
    if (filePointer == NULL) {
        perror("ファイルを開けませんでした");
        return 1;
    }
    while ((ch = fgetc(filePointer)) != EOF) {
        putchar(ch); // 読み込んだ文字を表示
    }
    fclose(filePointer);
    return 0;
}

このコードは、example.txtから1文字ずつ読み込み、読み込んだ文字を標準出力に表示します。

fgetc関数は、ファイルの終端に達するとEOFを返します。

fread関数によるバイナリデータの読み込み

fread関数は、バイナリデータを読み取るために使用されます。

以下は、fread関数を使ったサンプルコードです。

#include <stdio.h>
int main() {
    FILE *filePointer;
    unsigned char buffer[10]; // 読み込んだデータを格納するバッファ
    size_t bytesRead;
    filePointer = fopen("example.bin", "rb");
    if (filePointer == NULL) {
        perror("ファイルを開けませんでした");
        return 1;
    }
    bytesRead = fread(buffer, sizeof(unsigned char), sizeof(buffer), filePointer);
    printf("読み込んだバイト数: %zu\n", bytesRead);
    for (size_t i = 0; i < bytesRead; i++) {
        printf("%02x ", buffer[i]); // 読み込んだデータを16進数で表示
    }
    printf("\n");
    fclose(filePointer);
    return 0;
}

このコードは、example.binからバイナリデータを読み込み、読み込んだデータを16進数で表示します。

fread関数は、指定したサイズのデータを読み込み、その読み込んだ要素数を返します。

ファイルの内容を表示する

ファイルから読み取ったデータを表示する方法は、C言語においていくつか存在します。

このセクションでは、printf関数を使った出力、puts関数を使った出力、そして出力フォーマットの工夫について解説します。

printf関数を使った出力

printf関数は、フォーマット指定子を用いて、さまざまな形式でデータを出力することができます。

以下は、printf関数を使ってファイルの内容を表示するサンプルコードです。

#include <stdio.h>
int main() {
    FILE *filePointer;
    char buffer[256];
    filePointer = fopen("example.txt", "r");
    if (filePointer == NULL) {
        perror("ファイルを開けませんでした");
        return 1;
    }
    while (fgets(buffer, sizeof(buffer), filePointer) != NULL) {
        printf("読み込んだ行: %s", buffer); // 読み込んだ行をフォーマット付きで表示
    }
    fclose(filePointer);
    return 0;
}

このコードでは、example.txtから読み込んだ各行をprintf関数で表示しています。

printf関数は、文字列の中にフォーマット指定子(例:%s)を使用することで、変数の値を埋め込むことができます。

puts関数を使った出力

puts関数は、文字列を表示するための簡単な方法です。

改行を自動的に追加するため、行単位での出力に便利です。

以下は、puts関数を使ったサンプルコードです。

#include <stdio.h>
int main() {
    FILE *filePointer;
    char buffer[256];
    filePointer = fopen("example.txt", "r");
    if (filePointer == NULL) {
        perror("ファイルを開けませんでした");
        return 1;
    }
    while (fgets(buffer, sizeof(buffer), filePointer) != NULL) {
        puts(buffer); // 読み込んだ行を表示
    }
    fclose(filePointer);
    return 0;
}

このコードでは、example.txtから読み込んだ各行をputs関数で表示しています。

puts関数は、文字列の末尾に自動的に改行を追加するため、printf関数%s\nとするのと同様の効果があります。

出力フォーマットの工夫

出力フォーマットを工夫することで、データをより見やすく表示することができます。

以下は、出力フォーマットを工夫した例です。

#include <stdio.h>
int main() {
    FILE *filePointer;
    char buffer[256];
    int lineNumber = 1;
    filePointer = fopen("example.txt", "r");
    if (filePointer == NULL) {
        perror("ファイルを開けませんでした");
        return 1;
    }
    while (fgets(buffer, sizeof(buffer), filePointer) != NULL) {
        printf("行 %d: %s", lineNumber++, buffer); // 行番号を付けて表示
    }
    fclose(filePointer);
    return 0;
}

このコードでは、各行に行番号を付けて表示しています。

printf関数を使うことで、行番号やその他の情報を付加して出力することが可能です。

これにより、データの内容をより理解しやすくすることができます。

ファイルを閉じる

ファイルを操作した後は、必ずファイルを閉じる必要があります。

ファイルを閉じることは、プログラムの安定性と効率性を保つために非常に重要です。

このセクションでは、fclose関数の重要性とリソースリークを防ぐ方法について解説します。

fclose関数の重要性

fclose関数は、開いたファイルを閉じるために使用されます。

ファイルを閉じることには以下のような重要な理由があります。

  • リソースの解放: ファイルを開くと、オペレーティングシステムからファイルハンドルというリソースが割り当てられます。

fclose関数を呼び出すことで、このリソースを解放し、他のプロセスが利用できるようにします。

  • データの確実な保存: 書き込み操作を行った場合、fcloseを呼び出すことで、バッファに残っているデータがディスクに確実に書き込まれます。
  • ファイルの整合性: ファイルを閉じることで、ファイルシステムの整合性を保ち、データの破損を防ぎます。

以下は、fclose関数を使用したサンプルコードです。

#include <stdio.h>
int main() {
    FILE *filePointer;
    filePointer = fopen("example.txt", "r");
    if (filePointer == NULL) {
        perror("ファイルを開けませんでした");
        return 1;
    }
    // ファイル操作のコードをここに記述
    fclose(filePointer); // ファイルを閉じる
    return 0;
}

リソースリークを防ぐ方法

リソースリークとは、プログラムが終了するまでリソースが解放されない状態を指します。

これを防ぐためには、以下の方法を実践することが重要です。

  • 必ずfcloseを呼び出す: ファイルを開いたら、必ずfcloseを呼び出してファイルを閉じるようにします。

特に、エラーが発生した場合でも、ファイルを閉じる処理を忘れないようにします。

  • エラーチェックを行う: ファイル操作の各ステップでエラーチェックを行い、エラーが発生した場合は適切に対処します。
  • 関数の終了時にファイルを閉じる: 関数が終了する前に、開いたファイルをすべて閉じるようにします。

これにより、関数内で開いたファイルが確実に閉じられます。

以下は、リソースリークを防ぐためのサンプルコードです。

#include <stdio.h>
int main() {
    FILE *filePointer;
    filePointer = fopen("example.txt", "r");
    if (filePointer == NULL) {
        perror("ファイルを開けませんでした");
        return 1;
    }
    // ファイル操作のコードをここに記述
    if (fclose(filePointer) != 0) {
        perror("ファイルを閉じる際にエラーが発生しました");
        return 1;
    }
    return 0;
}

このコードでは、fclose関数の戻り値をチェックし、ファイルを閉じる際にエラーが発生した場合にエラーメッセージを表示しています。

これにより、リソースリークを防ぎ、プログラムの信頼性を向上させることができます。

エラーハンドリング

ファイル操作を行う際には、さまざまなエラーが発生する可能性があります。

これらのエラーを適切に処理することで、プログラムの信頼性と安定性を向上させることができます。

このセクションでは、ファイル操作中のエラー検出、perror関数strerror関数の使い方、そしてエラー処理のベストプラクティスについて解説します。

ファイル操作中のエラー検出

ファイル操作中にエラーが発生した場合、C言語では通常、関数が特定のエラー値を返します。

例えば、fopen関数はファイルを開けなかった場合にNULLを返します。

エラーを検出するためには、関数の戻り値をチェックすることが重要です。

以下は、ファイル操作中のエラーを検出するサンプルコードです。

#include <stdio.h>
int main() {
    FILE *filePointer;
    filePointer = fopen("nonexistent.txt", "r");
    if (filePointer == NULL) {
        perror("ファイルを開けませんでした");
        return 1;
    }
    // ファイル操作のコードをここに記述
    if (fclose(filePointer) != 0) {
        perror("ファイルを閉じる際にエラーが発生しました");
        return 1;
    }
    return 0;
}

このコードでは、fopenfcloseの戻り値をチェックし、エラーが発生した場合にperror関数を使用してエラーメッセージを表示しています。

perror関数とstrerror関数の使い方

perror関数strerror関数は、エラーメッセージを表示するために使用されます。

  • perror関数: 標準エラー出力にエラーメッセージを表示します。

errnoの値に基づいて、エラーの原因を示すメッセージを出力します。

#include <stdio.h>
  #include <errno.h>
  int main() {
      FILE *filePointer;
      filePointer = fopen("nonexistent.txt", "r");
      if (filePointer == NULL) {
          perror("ファイルを開けませんでした");
          return 1;
      }
      return 0;
  }
  • strerror関数: errnoの値に対応するエラーメッセージを文字列として返します。
#include <stdio.h>
  #include <string.h>
  #include <errno.h>
  int main() {
      FILE *filePointer;
      filePointer = fopen("nonexistent.txt", "r");
      if (filePointer == NULL) {
          printf("エラー: %s\n", strerror(errno));
          return 1;
      }
      return 0;
  }

エラー処理のベストプラクティス

エラー処理を適切に行うためのベストプラクティスを以下に示します。

  • 戻り値のチェック: ファイル操作関数の戻り値を常にチェックし、エラーが発生した場合に適切に対処します。
  • エラーメッセージの表示: perrorstrerrorを使用して、ユーザーにエラーの詳細を伝えます。
  • リソースの解放: エラーが発生した場合でも、開いたファイルや確保したメモリを適切に解放します。
  • 一貫したエラーハンドリング: プログラム全体で一貫したエラーハンドリングの方法を採用し、コードの可読性と保守性を向上させます。

これらのベストプラクティスを実践することで、エラーが発生した際にもプログラムが予期せぬ動作をしないようにすることができます。

応用例

ファイル操作の基本を理解したら、さまざまな応用例に挑戦することができます。

このセクションでは、テキストファイルの行数を数える方法、特定の文字列を検索する方法、そしてバイナリファイルの内容を解析する方法について解説します。

テキストファイルの行数を数える

テキストファイルの行数を数えるには、ファイルを1行ずつ読み込み、行が存在するたびにカウンタを増やします。

以下は、そのためのサンプルコードです。

#include <stdio.h>
int main() {
    FILE *filePointer;
    char buffer[256];
    int lineCount = 0;
    filePointer = fopen("example.txt", "r");
    if (filePointer == NULL) {
        perror("ファイルを開けませんでした");
        return 1;
    }
    while (fgets(buffer, sizeof(buffer), filePointer) != NULL) {
        lineCount++; // 行をカウント
    }
    printf("行数: %d\n", lineCount);
    fclose(filePointer);
    return 0;
}

このコードは、example.txtの行数を数え、結果を表示します。

fgets関数を使用して1行ずつ読み込み、行が存在するたびにlineCountをインクリメントしています。

特定の文字列を検索する

特定の文字列をファイル内で検索するには、各行を読み込み、strstr関数を使用して文字列を検索します。

以下は、そのためのサンプルコードです。

#include <stdio.h>
#include <string.h>
int main() {
    FILE *filePointer;
    char buffer[256];
    const char *searchString = "検索文字列";
    int lineNumber = 0;
    filePointer = fopen("example.txt", "r");
    if (filePointer == NULL) {
        perror("ファイルを開けませんでした");
        return 1;
    }
    while (fgets(buffer, sizeof(buffer), filePointer) != NULL) {
        lineNumber++;
        if (strstr(buffer, searchString) != NULL) {
            printf("行 %d に文字列が見つかりました: %s", lineNumber, buffer);
        }
    }
    fclose(filePointer);
    return 0;
}

このコードは、example.txt内で”検索文字列”を探し、見つかった行を表示します。

strstr関数を使用して、各行に検索文字列が含まれているかを確認しています。

バイナリファイルの内容を解析する

バイナリファイルの内容を解析するには、fread関数を使用してデータを読み込み、必要に応じて解析を行います。

以下は、そのためのサンプルコードです。

#include <stdio.h>
int main() {
    FILE *filePointer;
    unsigned char buffer[16];
    size_t bytesRead;
    size_t offset = 0;
    filePointer = fopen("example.bin", "rb");
    if (filePointer == NULL) {
        perror("ファイルを開けませんでした");
        return 1;
    }
    while ((bytesRead = fread(buffer, 1, sizeof(buffer), filePointer)) > 0) {
        printf("オフセット %04zx: ", offset);
        for (size_t i = 0; i < bytesRead; i++) {
            printf("%02x ", buffer[i]); // バイナリデータを16進数で表示
        }
        printf("\n");
        offset += bytesRead;
    }
    fclose(filePointer);
    return 0;
}

このコードは、example.binの内容を16進数で表示します。

fread関数を使用してバイナリデータを読み込み、各バイトを16進数形式で出力しています。

これにより、バイナリファイルの内容を解析することができます。

よくある質問

ファイルが開けないのはなぜ?

ファイルが開けない原因はいくつか考えられます。

まず、指定したファイル名が間違っている可能性があります。

ファイル名は大文字と小文字を区別するため、正確に指定する必要があります。

また、ファイルが存在しないか、アクセス権限が不足している場合も考えられます。

ファイルが存在するディレクトリにアクセス権があるか確認し、必要に応じて権限を変更してください。

例:chmod 644 ファイル名で権限を変更できます。

ファイルの終端を検出する方法は?

ファイルの終端を検出するには、fgetcfgetsなどの関数がEOFを返すかどうかを確認します。

EOFはファイルの終端を示す特別な値です。

例えば、fgetcを使用する場合、while ((ch = fgetc(filePointer)) != EOF)のようにループを構成します。

これにより、ファイルの終端に達するまで読み込みを続けることができます。

バイナリファイルとテキストファイルの違いは?

バイナリファイルとテキストファイルの主な違いは、データの格納形式です。

テキストファイルは、人間が読める形式でデータを保存し、通常は文字列として扱われます。

一方、バイナリファイルは、データをそのままのバイナリ形式で保存します。

これにより、画像や音声、実行ファイルなどのデータを効率的に格納できます。

バイナリファイルを操作する際は、freadfwriteを使用してデータを扱います。

まとめ

この記事では、C言語でファイルを操作する方法について詳しく解説しました。

ファイルの開閉、内容の読み取り、表示、エラーハンドリング、そして応用例を通じて、ファイル操作の基本から応用までを学びました。

これらの知識を活用して、より複雑なファイル操作を行うプログラムを作成してみてください。

  • URLをコピーしました!
目次から探す