Zenn
🦁

【Unity】改行含むcsvファイルを読み込むプログラム

に公開

目的


  • csvファイルを改行込みで読み込みたい

このプログラムは以下のゲームを作る際の知見です。
https://note.com/tebasakigames/n/n590df471a021

結論

//プロパティ定義
    public TextAsset csvFile; //メール本文
    public static List<List<string>> csvData = new List<List<string>>();

//~省略~

    //6行目の一列目のデータを取りたいとき
    //メールの文章を読み込む

    void Start()
    {
        csvData = CSVReader.ReadCSV(csvFile);
        Debug.Log(csvData[6][1]);
    }
using System.Collections.Generic;
using UnityEngine;
using System.Text;
using System.IO;

public static class CSVReader
{
  public static List<List<string>> ReadCSV(TextAsset csvFileToRead)
  {
    List<List<string>> csvData = new List<List<string>>();

    using (StringReader reader = new StringReader(csvFileToRead.text))
    {
      StringBuilder currentElement = new StringBuilder();
      List<string> currentRow = new List<string>();
      bool inQuotes = false;

      while (reader.Peek() > -1)
      {
        int c = reader.Read();
        char ch = (char)c;

        if (ch == '\"')
        {
          inQuotes = !inQuotes;
        }
        else if (ch == ',' && !inQuotes)
        {
          // カンマが区切り文字として機能する場合、現在のセルを確定
          currentRow.Add(currentElement.ToString().Trim());
          currentElement.Clear();
        }
        else if ((ch == '\n' || ch == '\r') && !inQuotes)
        {
          // 改行コードが現れた場合
          // Windows環境での "\r\n" に対応
          if (ch == '\r' && reader.Peek() == '\n')
          {
            reader.Read();
          }
          currentRow.Add(currentElement.ToString().Trim());
          csvData.Add(new List<string>(currentRow));
          currentRow.Clear();
          currentElement.Clear();
        }
        else
        {
          currentElement.Append(ch);
        }
      }
      // 最後の行が改行で終わっていない場合の処理
      if (currentElement.Length > 0 || currentRow.Count > 0)
      {
        currentRow.Add(currentElement.ToString().Trim());
        csvData.Add(new List<string>(currentRow));
      }
    }
    return csvData;
  }

  /// <summary>
  /// 指定文字列を含むセルの行・列のインデックスを返します。
  /// 見つからなかった場合は (-1, -1) を返します。
  /// </summary>
  public static (int row, int col) FindStringIndex(List<List<string>> csvData, string searchString)
  {
    for (int row = 0; row < csvData.Count; row++)
    {
      for (int col = 0; col < csvData[row].Count; col++)
      {
        if (csvData[row][col].Equals(searchString))
        {
          return (row, col);
        }
      }
    }
    return (-1, -1);
  }

  /// <summary>
  /// 指定文字列を含むセルの直下の行の同じ列の値を返します。
  /// 見つからない場合はエラーメッセージを返します。
  /// </summary>
  public static string FindNextRowValue(List<List<string>> csvData, string searchString)
  {
    var result = FindStringIndex(csvData, searchString);
    if (result.row != -1 && result.col != -1 && result.row + 1 < csvData.Count)
    {
      return csvData[result.row + 1][result.col];
    }
    return "検索結果が見つからないか、次の行が存在しません。";
  }
}

追記

2025年2月20日
大幅にコード修正。

2024年1月30日

            csvDatas[i].Add(lineData[i].Trim()); //これがないと見えない空白が入って大変困る

trim関数を追加。trim使わないと辞書型のkeyとかに設定しているとKeyNotFoundとかになり地獄を見た(https://zenn.dev/link/comments/4d8d6b42e769be)

Discussion

ログインするとコメントできます