[C言語] ファイルを読み込んで2次元配列に格納する

C言語でファイルからデータを読み込み、2次元配列に格納する方法について説明します。

まず、ファイルを開くためにfopen関数を使用します。次に、fscanffgetsを用いてファイルからデータを読み取ります。

読み取ったデータは、適切な型の2次元配列に格納します。配列のサイズは事前に決めておく必要があります。

最後に、ファイルを閉じるためにfclose関数を使用します。

この方法を用いることで、テキストファイルの内容を効率的に2次元配列に格納できます。

この記事でわかること
  • fscanfとfgetsを使ったファイルからのデータ読み込み方法
  • 2次元配列へのデータ格納と境界チェックの重要性
  • CSVやバイナリファイルの読み込み応用例
  • ファイル操作におけるエラーハンドリングの方法
  • fscanfとfgetsの違いと使い分け

目次から探す

ファイルからデータを読み込む

ファイルからデータを読み込むことは、C言語プログラミングにおいて非常に重要なスキルです。

ここでは、fscanffgetsの使い方、ファイルの終端を確認する方法、そしてデータのフォーマットに応じた読み込みについて解説します。

fscanfとfgetsの使い方

fscanffgetsは、ファイルからデータを読み込むための標準的な関数です。

それぞれの使い方を見ていきましょう。

  • fscanf

fscanfは、ファイルからフォーマットに従ってデータを読み込むための関数です。

以下に基本的な使い方を示します。

#include <stdio.h>
  int main() {
      FILE *file;
      int number;
      char name[50];
      // ファイルを読み込みモードで開く
      file = fopen("data.txt", "r");
      if (file == NULL) {
          printf("ファイルを開けませんでした。\n");
          return 1;
      }
      // ファイルからデータを読み込む
      fscanf(file, "%d %s", &number, name);
      printf("番号: %d, 名前: %s\n", number, name);
      // ファイルを閉じる
      fclose(file);
      return 0;
  }

上記のコードは、data.txtから整数と文字列を読み込みます。

fscanfは、指定したフォーマットに従ってデータを読み込むため、データの形式が一致している必要があります。

  • fgets

fgetsは、ファイルから1行ずつ文字列を読み込むための関数です。

以下に基本的な使い方を示します。

#include <stdio.h>
  int main() {
      FILE *file;
      char line[100];
      // ファイルを読み込みモードで開く
      file = fopen("data.txt", "r");
      if (file == NULL) {
          printf("ファイルを開けませんでした。\n");
          return 1;
      }
      // ファイルから1行ずつ読み込む
      while (fgets(line, sizeof(line), file)) {
          printf("%s", line);
      }
      // ファイルを閉じる
      fclose(file);
      return 0;
  }

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

改行文字も含まれるため、行単位での処理に適しています。

ファイルの終端を確認する方法

ファイルの終端を確認するには、feof関数を使用します。

feofは、ファイルポインタがファイルの終端に達したかどうかを判定します。

#include <stdio.h>
int main() {
    FILE *file;
    char line[100];
    // ファイルを読み込みモードで開く
    file = fopen("data.txt", "r");
    if (file == NULL) {
        printf("ファイルを開けませんでした。\n");
        return 1;
    }
    // ファイルの終端まで読み込む
    while (!feof(file)) {
        if (fgets(line, sizeof(line), file) != NULL) {
            printf("%s", line);
        }
    }
    // ファイルを閉じる
    fclose(file);
    return 0;
}

このコードでは、feofを使ってファイルの終端を確認しながら、fgetsで1行ずつ読み込んでいます。

データのフォーマットに応じた読み込み

ファイルからデータを読み込む際には、データのフォーマットに応じた適切な方法を選択することが重要です。

以下に、異なるフォーマットのデータを読み込む例を示します。

  • 整数と文字列の組み合わせ

fscanfを使用して、整数と文字列を組み合わせて読み込むことができます。

#include <stdio.h>
  int main() {
      FILE *file;
      int id;
      char name[50];
      file = fopen("data.txt", "r");
      if (file == NULL) {
          printf("ファイルを開けませんでした。\n");
          return 1;
      }
      while (fscanf(file, "%d %s", &id, name) != EOF) {
          printf("ID: %d, 名前: %s\n", id, name);
      }
      fclose(file);
      return 0;
  }
  • CSV形式のデータ

fgetsstrtokを組み合わせて、CSV形式のデータを読み込むことができます。

#include <stdio.h>
  #include <string.h>
  int main() {
      FILE *file;
      char line[100];
      char *token;
      file = fopen("data.csv", "r");
      if (file == NULL) {
          printf("ファイルを開けませんでした。\n");
          return 1;
      }
      while (fgets(line, sizeof(line), file)) {
          token = strtok(line, ",");
          while (token != NULL) {
              printf("%s ", token);
              token = strtok(NULL, ",");
          }
          printf("\n");
      }
      fclose(file);
      return 0;
  }

このように、データのフォーマットに応じて適切な関数や方法を選択することで、効率的にファイルからデータを読み込むことができます。

2次元配列へのデータ格納

ファイルから読み込んだデータを2次元配列に格納することは、データを効率的に管理し、操作するために重要です。

ここでは、ループを使ったデータの格納方法、配列の境界チェック、データの型変換とエラーハンドリングについて解説します。

ループを使ったデータの格納

2次元配列にデータを格納する際には、通常、ネストされたループを使用します。

以下に、ファイルから読み込んだデータを2次元配列に格納する例を示します。

#include <stdio.h>
#define ROWS 3
#define COLS 3
int main() {
    FILE *file;
    int data[ROWS][COLS];
    int i, j;
    // ファイルを読み込みモードで開く
    file = fopen("matrix.txt", "r");
    if (file == NULL) {
        printf("ファイルを開けませんでした。\n");
        return 1;
    }
    // 2次元配列にデータを格納
    for (i = 0; i < ROWS; i++) {
        for (j = 0; j < COLS; j++) {
            fscanf(file, "%d", &data[i][j]);
        }
    }
    // 配列の内容を表示
    for (i = 0; i < ROWS; i++) {
        for (j = 0; j < COLS; j++) {
            printf("%d ", data[i][j]);
        }
        printf("\n");
    }
    // ファイルを閉じる
    fclose(file);
    return 0;
}

このコードでは、matrix.txtから整数を読み込み、3×3の2次元配列に格納しています。

ネストされたループを使用することで、行と列を指定してデータを格納できます。

配列の境界チェック

配列の境界を超えてデータを格納しようとすると、プログラムが予期しない動作をする可能性があります。

境界チェックを行うことで、このようなエラーを防ぐことができます。

#include <stdio.h>
#define ROWS 3
#define COLS 3
int main() {
    FILE *file;
    int data[ROWS][COLS];
    int i, j;
    int value;
    file = fopen("matrix.txt", "r");
    if (file == NULL) {
        printf("ファイルを開けませんでした。\n");
        return 1;
    }
    for (i = 0; i < ROWS; i++) {
        for (j = 0; j < COLS; j++) {
            if (fscanf(file, "%d", &value) == 1) {
                data[i][j] = value;
            } else {
                printf("データの読み込みに失敗しました。\n");
                fclose(file);
                return 1;
            }
        }
    }
    fclose(file);
    return 0;
}

このコードでは、fscanfの戻り値をチェックすることで、データの読み込みが成功したかどうかを確認しています。

これにより、配列の境界を超えたデータの格納を防ぐことができます。

データの型変換とエラーハンドリング

ファイルから読み込んだデータが期待する型と異なる場合、型変換を行う必要があります。

また、エラーハンドリングを適切に行うことで、プログラムの安定性を向上させることができます。

#include <stdio.h>
#include <stdlib.h>
#define ROWS 3
#define COLS 3
int main() {
    FILE *file;
    int data[ROWS][COLS];
    int i, j;
    char buffer[100];
    file = fopen("matrix.txt", "r");
    if (file == NULL) {
        printf("ファイルを開けませんでした。\n");
        return 1;
    }
    for (i = 0; i < ROWS; i++) {
        for (j = 0; j < COLS; j++) {
            if (fgets(buffer, sizeof(buffer), file) != NULL) {
                data[i][j] = atoi(buffer); // 文字列を整数に変換
            } else {
                printf("データの読み込みに失敗しました。\n");
                fclose(file);
                return 1;
            }
        }
    }
    fclose(file);
    return 0;
}

このコードでは、fgetsで読み込んだ文字列をatoi関数で整数に変換しています。

型変換を行うことで、異なるデータ型のデータを適切に処理できます。

また、エラーハンドリングを行うことで、データの読み込みに失敗した場合に適切な対応が可能です。

応用例

ファイルからデータを読み込んで2次元配列に格納する技術は、さまざまな応用が可能です。

ここでは、CSVファイルの読み込み、テキストファイルからのマトリックスデータの読み込み、バイナリファイルの読み込みと2次元配列への格納について解説します。

CSVファイルの読み込み

CSVファイルは、カンマで区切られたデータを持つファイル形式です。

fgetsstrtokを組み合わせて、CSVファイルを読み込むことができます。

#include <stdio.h>
#include <string.h>
#define ROWS 3
#define COLS 3
int main() {
    FILE *file;
    int data[ROWS][COLS];
    char line[100];
    char *token;
    int i = 0, j;
    // CSVファイルを読み込みモードで開く
    file = fopen("data.csv", "r");
    if (file == NULL) {
        printf("ファイルを開けませんでした。\n");
        return 1;
    }
    // CSVファイルからデータを読み込む
    while (fgets(line, sizeof(line), file) && i < ROWS) {
        j = 0;
        token = strtok(line, ",");
        while (token != NULL && j < COLS) {
            data[i][j] = atoi(token); // 文字列を整数に変換
            token = strtok(NULL, ",");
            j++;
        }
        i++;
    }
    // 配列の内容を表示
    for (i = 0; i < ROWS; i++) {
        for (j = 0; j < COLS; j++) {
            printf("%d ", data[i][j]);
        }
        printf("\n");
    }
    // ファイルを閉じる
    fclose(file);
    return 0;
}

このコードでは、CSVファイルからデータを読み込み、2次元配列に格納しています。

strtokを使用してカンマで区切られたデータを分割し、atoiで整数に変換しています。

テキストファイルからのマトリックスデータの読み込み

テキストファイルに保存されたマトリックスデータを2次元配列に読み込むことも一般的です。

以下にその例を示します。

#include <stdio.h>
#define ROWS 3
#define COLS 3
int main() {
    FILE *file;
    int matrix[ROWS][COLS];
    int i, j;
    // テキストファイルを読み込みモードで開く
    file = fopen("matrix.txt", "r");
    if (file == NULL) {
        printf("ファイルを開けませんでした。\n");
        return 1;
    }
    // テキストファイルからマトリックスデータを読み込む
    for (i = 0; i < ROWS; i++) {
        for (j = 0; j < COLS; j++) {
            fscanf(file, "%d", &matrix[i][j]);
        }
    }
    // 配列の内容を表示
    for (i = 0; i < ROWS; i++) {
        for (j = 0; j < COLS; j++) {
            printf("%d ", matrix[i][j]);
        }
        printf("\n");
    }
    // ファイルを閉じる
    fclose(file);
    return 0;
}

このコードは、テキストファイルから整数のマトリックスを読み込み、2次元配列に格納しています。

fscanfを使用して、ファイルから直接整数を読み込んでいます。

バイナリファイルの読み込みと2次元配列への格納

バイナリファイルは、データをバイナリ形式で保存するため、テキストファイルよりも効率的にデータを読み書きできます。

以下に、バイナリファイルからデータを読み込む例を示します。

#include <stdio.h>
#define ROWS 3
#define COLS 3
int main() {
    FILE *file;
    int data[ROWS][COLS];
    // バイナリファイルを読み込みモードで開く
    file = fopen("data.bin", "rb");
    if (file == NULL) {
        printf("ファイルを開けませんでした。\n");
        return 1;
    }
    // バイナリファイルからデータを読み込む
    fread(data, sizeof(int), ROWS * COLS, file);
    // 配列の内容を表示
    for (int i = 0; i < ROWS; i++) {
        for (int j = 0; j < COLS; j++) {
            printf("%d ", data[i][j]);
        }
        printf("\n");
    }
    // ファイルを閉じる
    fclose(file);
    return 0;
}

このコードでは、freadを使用してバイナリファイルからデータを読み込み、2次元配列に格納しています。

バイナリファイルは、データのサイズと形式を正確に把握している場合に特に有効です。

よくある質問

ファイルが見つからない場合はどうすればいいですか?

ファイルが見つからない場合、fopen関数NULLを返します。

この場合、ファイルが存在しないか、パスが間違っている可能性があります。

ファイルのパスを確認し、正しいパスを指定してください。

また、ファイルが存在するディレクトリにアクセス権があるかも確認してください。

例:if (file == NULL) { printf("ファイルを開けませんでした。\n"); }

配列のサイズを動的に変更できますか?

C言語では、静的配列のサイズを変更することはできませんが、動的メモリ割り当てを使用することで、配列のサイズを動的に変更することができます。

mallocrealloc関数を使用して、必要なサイズのメモリを割り当てることができます。

例:int *array = (int *)malloc(size * sizeof(int));

fscanfとfgetsの違いは何ですか?

fscanffgetsは、どちらもファイルからデータを読み込むための関数ですが、用途が異なります。

fscanfは、フォーマット指定子を使用して、特定のデータ型にデータを変換しながら読み込むことができます。

一方、fgetsは、ファイルから1行ずつ文字列としてデータを読み込みます。

fgetsは改行文字を含むため、行単位での処理に適しています。

まとめ

ファイルからデータを読み込んで2次元配列に格納する方法は、C言語プログラミングにおいて重要なスキルです。

この記事では、ファイルの読み込み方法、2次元配列へのデータ格納、応用例、よくある質問について解説しました。

これらの知識を活用して、より複雑なデータ処理を行うことができるようになります。

ぜひ、実際にコードを書いて試してみてください。

当サイトはリンクフリーです。出典元を明記していただければ、ご自由に引用していただいて構いません。

関連カテゴリーから探す

  • 標準入出力 (47)
  • ファイル (76)
  • URLをコピーしました!
目次から探す