🦁
【Unity】改行含むcsvファイルを読み込むプログラム
目的
- csvファイルを改行込みで読み込みたい
このプログラムは以下のゲームを作る際の知見です。
結論
//プロパティ定義
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