【保存版】C言語『getc』関数:ファイルから文字を賢く読み込むテクニック


getc 関数の基本

  • 引数:
    • stream: 読み込み対象のファイルストリームポインタ。fopen 関数などで取得します。
  • 戻り値: 次に読み込む文字 (成功した場合)。ファイルの末尾に達した場合は EOF を返します。
  • ヘッダーファイル: <stdio.h>

getc 関数の動作

  1. stream で指定されたファイルストリームから 1文字 読み込みます。
  2. 読み込んだ文字を int 型に変換して返します。
  3. ファイルの末尾に達すると、EOF マクロ (通常は -1 として定義されています) を返します。
  4. エラーが発生した場合は、EOF を返します。

getc 関数の使い方

#include <stdio.h>

int main() {
  FILE *fp;
  int c;

  // ファイルを開く
  fp = fopen("test.txt", "r");
  if (fp == NULL) {
    printf("ファイルを開けませんでした。\n");
    return 1;
  }

  // ファイルから文字を1文字ずつ読み込む
  while ((c = getc(fp)) != EOF) {
    putchar(c);  // 読み込んだ文字を画面に出力
  }

  // ファイルを閉じる
  fclose(fp);

  return 0;
}

この例では、"test.txt" というファイルを開き、その中の文字を1文字ずつ読み込んで画面に出力しています。

getc 関数の注意点

  • エラー処理を適切に行う必要があります。
  • ファイルの終端に達したかどうかは、EOF を使って判断する必要があります。
  • getc 関数は 1文字ずつ しか読み込みません。複数バイトの文字 (例: ワイド文字) を読み込む場合は、適切な関数を使用する必要があります。

getc 関数の応用例

  • シリアル通信
  • 文字列処理
  • バイナリファイルの読み込み
  • テキストファイルの読み込み

getc 関数は、ファイル入出力を行うための様々な関数の一つです。以下に、よく使用される他の関数をご紹介します。

  • fprintf: ファイルにデータをフォーマット付きで書き込む
  • fscanf: ファイルからデータをフォーマット付きで読み込む
  • fwrite: ファイルにデータをブロック単位で書き込む
  • fread: ファイルからデータをブロック単位で読み込む
  • fclose: ファイルを閉じる
  • fopen: ファイルを開く


ファイルの内容をすべて読み込む

#include <stdio.h>

int main() {
  FILE *fp;
  int c;

  // ファイルを開く
  fp = fopen("test.txt", "r");
  if (fp == NULL) {
    printf("ファイルを開けませんでした。\n");
    return 1;
  }

  // ファイルの内容をすべて読み込む
  while ((c = getc(fp)) != EOF) {
    putchar(c);
  }

  // ファイルを閉じる
  fclose(fp);

  return 0;
}

このコードは、"test.txt" というファイルを開き、その中の内容をすべて画面に出力します。

ファイルから文字列を読み込む

#include <stdio.h>

int main() {
  FILE *fp;
  char str[100];
  int i = 0;

  // ファイルを開く
  fp = fopen("test.txt", "r");
  if (fp == NULL) {
    printf("ファイルを開けませんでした。\n");
    return 1;
  }

  // ファイルから文字列を読み込む
  while ((c = getc(fp)) != EOF && i < sizeof(str) - 1) {
    str[i] = (char)c;
    i++;
  }

  str[i] = '\0';  // 文字列の終端記号を追加

  // 読み込んだ文字列を画面に出力
  printf("%s\n", str);

  // ファイルを閉じる
  fclose(fp);

  return 0;
}

このコードは、"test.txt" というファイルを開き、その中の最初の100文字までの文字列を読み込んで画面に出力します。

ファイルから1行ずつ読み込む

#include <stdio.h>

int main() {
  FILE *fp;
  char line[1024];

  // ファイルを開く
  fp = fopen("test.txt", "r");
  if (fp == NULL) {
    printf("ファイルを開けませんでした。\n");
    return 1;
  }

  // ファイルから1行ずつ読み込む
  while (fgets(line, sizeof(line), fp) != NULL) {
    printf("%s", line);
  }

  // ファイルを閉じる
  fclose(fp);

  return 0;
}
#include <stdio.h>

int main() {
  FILE *fp;
  int data[10];
  int i;

  // ファイルを開く
  fp = fopen("data.bin", "rb");
  if (fp == NULL) {
    printf("ファイルを開けませんでした。\n");
    return 1;
  }

  // ファイルからデータを10個読み込む
  for (i = 0; i < 10; i++) {
    if (fread(&data[i], sizeof(int), 1, fp) != 1) {
      printf("データの読み込みに失敗しました。\n");
      break;
    }
  }

  // 読み込んだデータを画面に出力
  for (i = 0; i < 10; i++) {
    printf("%d ", data[i]);
  }
  printf("\n");

  // ファイルを閉じる
  fclose(fp);

  return 0;
}


fgetc 関数

  • 引数:
    • stream: 読み込み対象のファイルストリームポインタ。fopen 関数などで取得します。
  • 戻り値: 次に読み込む文字 (成功した場合)。ファイルの末尾に達した場合は EOF を返します。
  • ヘッダーファイル: <stdio.h>
  • マルチスレッド環境での使用に適しています。
  • マクロではなく関数として定義されているため、getc 関数よりも安全に使用できます。
  • getc 関数とほぼ同じ機能を備えています。
#include <stdio.h>

int main() {
  FILE *fp;
  int c;

  // ファイルを開く
  fp = fopen("test.txt", "r");
  if (fp == NULL) {
    printf("ファイルを開けませんでした。\n");
    return 1;
  }

  // ファイルから文字を1文字ずつ読み込む
  while ((c = fgetc(fp)) != EOF) {
    putchar(c);  // 読み込んだ文字を画面に出力
  }

  // ファイルを閉じる
  fclose(fp);

  return 0;
}

getchar 関数

  • 引数: なし
  • 戻り値: 次に読み込む文字 (成功した場合)。入力待ち中に EOF を押すと EOF を返します。
  • ヘッダーファイル: <stdio.h>
  • ファイル入出力だけでなく、キーボードからの入力にも使用できます。
  • 標準入力ストリーム (stdin) から文字を1文字ずつ読み込みます。
#include <stdio.h>

int main() {
  int c;

  // 標準入力から文字を1文字ずつ読み込む
  while ((c = getchar()) != EOF) {
    putchar(c);  // 読み込んだ文字を画面に出力
  }

  return 0;
}
  • カスタム関数: 特定のニーズに合わせたファイル入出力処理を行う関数を作成します。
  • fread 関数: ファイルからバイナリデータをブロック単位で読み込みます。
  • fgets 関数: ファイルから1行ずつ文字列を読み込みます。

各代替方法の比較

関数名長所短所使用例
getcシンプルで使いやすいマクロで実装されているため、マルチスレッド環境では安全に使用できない可能性があるファイルから文字単位でデータを読み込む
fgetc安全に使用できるgetc 関数よりも少し低速マルチスレッド環境でのファイル入出力
getchar標準入力からの入力にも使用できる改行文字 (\n) を読み込むには工夫が必要キーボードからの入力
fgets1行ずつ文字列を読み込めるファイルの終端に達したかどうかを判断するのが難しいファイルから1行ずつ文字列を読み込む
freadバイナリデータの読み込みに適している文字列の読み込みには不向きファイルからバイナリデータをブロック単位で読み込む
カスタム関数特定のニーズに柔軟に対応できる開発に手間がかかる複雑なファイル入出力処理

状況に応じて適切な代替方法を選択することが重要です。

  • 複雑なファイル入出力処理にはカスタム関数
  • バイナリデータの読み込みに適している fread 関数
  • 1行ずつ文字列を読み込める fgets 関数
  • 標準入力からの入力にも使用できる getchar 関数
  • 安全に使用できる fgetc 関数
  • シンプルで使いやすい getc 関数