CSVファイルからStudentインスタンスを生成するサンプル

2025年8月7日

この記事の目的

  • CSV(カンマ区切りテキスト)形式のファイルからデータを読み取り、
  • C# のクラスインスタンスにマッピングする手順を学ぶ
  • 読み取ったインスタンスをコンソールに出力する

前提

  • .NET 6.0 以降が動作する環境
  • Visual Studio 2022 などでコンソールアプリケーションを作成できること
  • 実行フォルダに「data.csv」を配置していること

プロジェクト名 StudentCsvImporterで作成します

(ヒント)実行フォルダにVisualStudioの設定で配置する方法

CSVファイルの追加

  1. プロジェクトを右クリック
  2. 追加を選択
  3. 新しい項目を選択

ファイルの作成

  1. テキストファイルを選択
  2. ファイル名を入力
  3. 追加ボタンを押下

実行フォルダにコピーするプロパティの設定

サンプルデータ(data.csv)

1,佐藤,170
2,鈴木,165
3,高橋,180
  • 項目順:ID, 名前, 身長(cm)
  • 行数:3 行

1. Student クラスの定義

/// <summary>
/// 学生情報を表すクラス
/// </summary>
public class Student
{
    public int Id { get; }
    public string Name { get; }
    public int Height { get; }

    public Student(int id, string name, int height)
    {
        Id     = id;
        Name   = name;
        Height = height;
    }

    public override string ToString()
    {
        return $"ID={Id}, 名前={Name}, 身長={Height}cm";
    }
}

2. CSVファイルの読み込みとパース

以下の手順で CSV を読み込み、List<Student> を作成します。

  1. File.ReadAllLines で全行を取得
  2. string.Split(',’) でフィールドに分割
  3. int.TryParse で ID と身長を数値変換
  4. new Student(…) でインスタンス化し、リストに追加
using System;
using System.Collections.Generic;
using System.IO;

namespace StudentCsvImporter
{
    class Program
    {
        static void Main()
        {
            const string filePath = "data.csv";
            var students = new List<Student>();

            var lines = File.ReadAllLines(filePath);

            foreach (var line in lines)
            {
                var parts = line.Split(',');

                int id = int.Parse(parts[0]);
                string name = parts[1];
                int height = int.Parse(parts[2]);
                var student = new Student(id, name, height);

                students.Add(student);
            }

            Console.WriteLine("=== 読み込んだ学生情報 ===");

            foreach (var s in students)
            {
                Console.WriteLine(s);
            }
        }
    }
}

1. 全体構成

using System;
using System.Collections.Generic;
using System.IO;

class Program
{
    static void Main()
    {
        // … ファイル読み込み&リスト生成 …
    }
}

internal class Student
{
    // … プロパティ&ToString override …
}
  • using System;/using System.Collections.Generic;:基本機能とジェネリックリストを使うため
  • using System.IO;:ファイル入出力(File.ReadAllLines)を使うため
  • Program クラス:エントリポイントとして CSV を読み込む
  • Student クラス:CSV の1行分を表すデータモデル

2. Program クラスと Main メソッド

static void Main()
{
    const string filePath = "data.csv";
    var students = new List<Student>();

    var lines = File.ReadAllLines(filePath);

    foreach (var line in lines)
    {
        var parts = line.Split(',');

        int id = int.Parse(parts[0]);
        string name = parts[1];
        int height = int.Parse(parts[2]);
        var student = new Student(id, name, height);

        students.Add(student);
    }

    Console.WriteLine("=== 読み込んだ学生情報 ===");

    foreach (var s in students)
    {
        Console.WriteLine(s);
    }
}
  1. ファイルパスとリスト初期化
    • filePath に読み込む CSV ファイル名を定数として定義
    • students リストを空で生成
  2. CSV 全行読み込み
    • File.ReadAllLines(filePath) でファイルの各行を文字列配列として取得
  3. 行ごとのパース処理
    • line.Split(',’) でカンマ区切りに分割し、parts 配列に格納
    • parts[0] → ID、parts[1] → 名前、parts[2] → 身長
    • int.Parse で文字列から整数へ変換
    • new Student(…) で Student インスタンスを生成し、リストに追加
  4. 読み込み結果の表示
    • Console.WriteLine(“=== 読み込んだ学生情報 ==="); に続けて
    • students リストを foreach で回し、ToString() を用いて各行をコンソール出力

3. Student クラス

internal class Student
{
    // 1. プロパティ(データ表現)
    public int Id { get; }
    public string Name { get; }
    public int Height { get; }

    // 2. コンストラクター(初期化)
    public Student(int id, string name, int height)
    {
        Id = id;
        Name = name;
        Height = height;
    }

    // 3. オーバーライドしたメソッド(振る舞い)
    public override string ToString()
    {
        return $"ID={Id}, 名前={Name}, 身長={Height}cm";
    }
}
  • プロパティ
    • Id・Name・Height は外部から読み取りのみ可能
  • コンストラクタ
    • 引数で渡された id/name/height を読み取り専用プロパティにセット
  • ToString のオーバーライド
    • Console.WriteLine(s) の際、自動的にこの文字列が表示される
    • 可読性の高い出力フォーマットを提供

4. 学習ポイント

  1. ファイル I/O の基本
    • File.ReadAllLines によるファイル全行読み込み
    • 例外処理(ファイル未検出やフォーマット異常)は入門段階では省略し、まずは動作を理解
  2. 文字列操作
    • string.Split による簡易パーシング
    • 数値変換時の例外(FormatException)も後段で扱える
  3. OOP によるデータモデル化
    • CSV の各行を Student クラスというオブジェクトにマッピング
    • ToString を活用し、出力ロジックをモデル側にカプセル化
  4. 責務分割
    • Program.Main:ファイル読み込みとリスト管理、表示の全体フロー
    • Student:1件分のデータ保持と文字列表現

この設計をベースに、たとえば「ヘッダー行のスキップ」「カンマ以外のデリミタ対応」「例外処理の追加」「List<T> でなく IEnumerable<T> や LINQ を使った一行パース」など、徐々に拡張していく練習ができます。

using System;
using System.Collections.Generic;
using System.IO;

namespace StudentCsvImporter
{
    class Program
    {
        static void Main()
        {
            const string filePath = "data.csv";
            var students = new List<Student>();

            var lines = File.ReadAllLines(filePath);

            foreach (var line in lines)
            {
                var parts = line.Split(',');

                int id = int.Parse(parts[0]);
                string name = parts[1];
                int height = int.Parse(parts[2]);
                var student = new Student(id, name, height);

                students.Add(student);
            }

            Console.WriteLine("=== 読み込んだ学生情報 ===");

            foreach (var s in students)
            {
                Console.WriteLine(s);
            }
        }
    }

    internal class Student
    {
        // 1. プロパティ(データ表現)
        public int Id { get; }
        public string Name { get; }
        public int Height { get; }

        // 2. コンストラクター(初期化)
        public Student(int id, string name, int height)
        {
            Id = id;
            Name = name;
            Height = height;
        }

        // 3. オーバーライドしたメソッド(振る舞い)
        public override string ToString()
        {
            return $"ID={Id}, 名前={Name}, 身長={Height}cm";
        }
    }
}

エラー処理を付加したコード

using System;
using System.Collections.Generic;
using System.IO;

class Program
{
    static void Main()
    {
        const string filePath = "data.csv";
        var students = new List<Student>();

        try
        {
            var lines = File.ReadAllLines(filePath);

            foreach (var line in lines)
            {
                var parts = line.Split(',');

                if (parts.Length != 3)
                {
                    Console.WriteLine($"警告: 不正な行をスキップ → \"{line}\"");
                    continue;
                }

                if (int.TryParse(parts[0], out int id)
                    && int.TryParse(parts[2], out int height))
                {
                    string name = parts[1];
                    var student = new Student(id, name, height);
                    students.Add(student);
                }
                else
                {
                    Console.WriteLine($"警告: 数値変換に失敗 → \"{line}\"");
                }
            }

            Console.WriteLine("=== 読み込んだ学生情報 ===");
            foreach (var s in students)
            {
                Console.WriteLine(s);
            }
        }
        catch (IOException ex)
        {
            Console.WriteLine($"ファイル読み込みエラー: {ex.Message}");
        }
    }
}

1. 全体構成

using System;
using System.Collections.Generic;
using System.IO;

class Program
{
    static void Main()
    {
        // … CSV 読み込み&バリデーション&例外処理 …
    }
}
  • using System;/using System.Collections.Generic;:基本機能とジェネリックコレクションを利用
  • using System.IO;:ファイル操作(File.ReadAllLines)と例外型 (IOException) を利用
  • Program クラス:エントリポイントとして CSV の読み込み~出力の一連処理を担当

※Student クラスは前回の例と同様に、Id・Name・Height プロパティと ToString() を持つ想定です。


2. Main メソッドの流れ

const string filePath = "data.csv";
var students = new List<Student>();
  • ファイルパス定義:定数 filePath
  • 結果格納リスト:students を初期化
try
{
    var lines = File.ReadAllLines(filePath);
    // … 各行の処理 …
}
catch (IOException ex)
{
    Console.WriteLine($"ファイル読み込みエラー: {ex.Message}");
}
  • 例外ハンドリング
    • ファイルが存在しない、アクセス権限エラー等の IOException をキャッチ
    • キャッチ時はエラーメッセージを表示してプログラム継続

3. 各行のパース&バリデーション

foreach (var line in lines)
{
    var parts = line.Split(',');
  • カンマ分割:line.Split(',’) で配列化
    if (parts.Length != 3)
    {
        Console.WriteLine($"警告: 不正な行をスキップ → \"{line}\"");
        continue;
    }
  • 項目数チェック
    • Id,Name,Height の 3 要素でなければ警告を出して次行へ
    if (int.TryParse(parts[0], out int id)
        && int.TryParse(parts[2], out int height))
    {
        string name = parts[1];
        var student = new Student(id, name, height);
        students.Add(student);
    }
    else
    {
        Console.WriteLine($"警告: 数値変換に失敗 → \"{line}\"");
    }
  • 数値変換チェック
    • TryParse を使い、ID と身長が整数であることを検証
    • 成功時のみ Student を生成・追加
    • 失敗時は警告メッセージを出力

4. 読み込み結果の表示

Console.WriteLine("=== 読み込んだ学生情報 ===");
foreach (var s in students)
{
    Console.WriteLine(s);
}
  • ヘッダー出力
  • ToString() 呼び出し
    • Student 側でオーバーライドした出力フォーマット(例:ID=1, 名前=山田, 身長=168cm)が利用される

5. 学習ポイント

  1. 例外処理による堅牢性
    • try~catch で I/O エラーをキャッチし、アプリケーションの異常終了を防ぐ
  2. 入力データのバリデーション
    • 項目数チェック → 不正行スキップ
    • TryParse → 数値変換失敗時は警告出力
  3. ユーザーへのフィードバック
    • スキップや変換失敗をコンソールに明示することで、後からログを確認しやすい
  4. OOP による役割分担
    • Program:読み込み・検証・例外対応・一覧出力
    • Student:データ保持と表示フォーマット
  5. 拡張・改良の余地
    • ヘッダー行の自動スキップ
    • セミコロンやタブ区切りへの対応
    • 不正行を別ファイルへ書き出すログ機能
    • JSON や XML への出力置き換え

このように、実践的なエラーチェックと例外処理を組み込むことで、CSV パーサの信頼性と保守性が大きく向上します。


4. 実行結果イメージ

=== 読み込んだ学生情報 ===
ID=1, 名前=佐藤, 身長=170cm
ID=2, 名前=鈴木, 身長=165cm
ID=3, 名前=高橋, 身長=180cm

まとめ

CSV ファイルの読み込みとクラスインスタンス生成は、業務アプリケーションでよく使われる基本パターンです。本サンプルを基に、以下のような応用にも挑戦してみてください。

  • 区切り文字を変更(タブやセミコロンなど)
  • 大規模データ向けに File.ReadLines を利用
  • 複雑な CSV は外部ライブラリ(CsvHelper など)を導入して効率化

この流れを身につけて、より堅牢で拡張性の高いファイル I/O を実現しましょう。

参考

次のコードはいずれもまとめたコードになります
そのまま、貼り付けることができます

インスタンスのファイルへの書き出し

using System;
using System.Collections.Generic;
using System.IO;

namespace StudentCsvExporter
{
    class Program
    {
        static void Main()
        {
            const string inputPath  = "data.csv";
            const string outputPath = "output.csv";

            // 1. CSV 読み込み → List<Student> に格納
            var students = new List<Student>();
            var lines = File.ReadAllLines(inputPath);
            foreach (var line in lines)
            {
                var parts = line.Split(',');
                int id     = int.Parse(parts[0]);
                string name = parts[1];
                int height = int.Parse(parts[2]);

                students.Add(new Student(id, name, height));
            }

            // (必要に応じて students を加工)

            // 2. List<Student> から書き出し用の文字列リストを作成
            var outputLines = new List<string>();
            foreach (var s in students)
            {
                // フィールドを再び CSV 形式の文字列に
                outputLines.Add($"{s.Id},{s.Name},{s.Height}");
            }

            // 3. output.csv へ一括書き出し
            File.WriteAllLines(outputPath, outputLines);

            Console.WriteLine($"Saved {students.Count} records to {outputPath}");
        }
    }

    internal class Student
    {
        public int    Id     { get; }
        public string Name   { get; }
        public int    Height { get; }

        public Student(int id, string name, int height)
        {
            Id     = id;
            Name   = name;
            Height = height;
        }

        public override string ToString() =>
            $"ID={Id}, 名前={Name}, 身長={Height}cm";
    }
}

エラー処理あり

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;

namespace StudentCsvImporter
{
    class Program
    {
        static void Main()
        {
            const string inputPath  = "data.csv";
            const string outputPath = "output.csv";
            
            // 1. CSV 読み込み → List<Student> 生成
            var students = new List<Student>();
            var lines = File.ReadAllLines(inputPath);
            foreach (var line in lines)
            {
                var parts = line.Split(',');
                if (parts.Length != 3) continue;

                if (int.TryParse(parts[0], out int id)
                 && int.TryParse(parts[2], out int height))
                {
                    students.Add(new Student(id, parts[1], height));
                }
            }

            // (必要に応じて students を加工)

            // 2. 保存用文字列リストを生成
            var outputLines = students
                .Select(s => $"{s.Id},{s.Name},{s.Height}")
                .ToArray();

            // 3. CSV ファイルへ書き出し
            try
            {
                File.WriteAllLines(outputPath, outputLines);
                Console.WriteLine($"Saved {students.Count} records to {outputPath}");
            }
            catch (IOException ex)
            {
                Console.WriteLine($"書き込みエラー: {ex.Message}");
            }
        }
    }

    /// <summary>
    /// 学生情報を表すクラス
    /// </summary>
    internal class Student
    {
        public int    Id     { get; }
        public string Name   { get; }
        public int    Height { get; }

        public Student(int id, string name, int height)
        {
            Id     = id;
            Name   = name;
            Height = height;
        }

        public override string ToString() =>
            $"ID={Id}, 名前={Name}, 身長={Height}cm";
    }
}
訪問数 61 回, 今日の訪問数 1回

C#,File

Posted by hidepon