Unity导入CSV时末尾Dictionary键值对未加入List异常
Unity CSV读取脚本末位键值对查询异常问题
问题现象
- 模块化CSV读取脚本整体运行基本正常,但存在异常:最后一组键值对确认存在于Dictionary实例内,却无法通过指定键名从List存储的字典中正常访问
- 遍历单行数据对应的singleCard字典时,可正常打印输出
Alignment TopLeft键值对 - 访问
allCards[2]["PrefabName"]可正常返回预期值test3,但访问allCards[2]["Alignment"]时抛出KeyNotFoundException,提示字典中不存在"Alignment"键
原始实现代码
string[] data = fileString.Split(new string[] {";", "\n"}, StringSplitOptions.None); Debug.Log(data.Length); int rows = data.Length / columns - 1; List<string> kartenvariablen = new List<string>(); for (int i = 0; i<= columns; i++) { kartenvariablen.Add(data[i]); } Debug.Log(kartenvariablen.Count); Debug.Log(kartenvariablen[9]); List<Dictionary<string, string>> allCards = new List<Dictionary<string, string>>(); for(int i=0; i< rows; i++) { Dictionary<string, string> singleCard = new Dictionary<string, string>(); for(int n= 0; n <= columns; n++) { singleCard.Add(kartenvariablen[n], data[columns+1+n+(i*(columns+1))]); } foreach (KeyValuePair<string, string> s in singleCard) { Debug.Log(s); //此处打印可见Alignment TopLeft键值对 } allCards.Add(singleCard); } Debug.Log(allCards[2]["PrefabName"]); //正常返回test3 Debug.Log(allCards[2]["Alignment"]); //抛出KeyNotFoundException: The given key 'Alignment' was not present in the dictionary.
报错堆栈
System.Collections.Generic.Dictionary`2[TKey,TValue].get_Item (TKey key) (at <6073cf49ed704e958b8a66d540dea948>:0) CSVTemplateReader.ReadCSV () (at Assets/Scripts/CSVTemplateReader.cs:106) CSVTemplateReader.Start () (at Assets/Scripts/CSVTemplateReader.cs:19)
问题根因
- 分隔符处理遗漏回车符:代码仅使用
\n作为换行分割符,Windows环境下文本文件默认换行符为\r\n,分割后每行最后一列的表头、字段值末尾都会携带不可见的\r字符。遍历字典打印时\r为不可见控制符,肉眼看到的键名是"Alignment",实际字典中存储的键为"Alignment\r",使用无\r后缀的"Alignment"查询自然触发键不存在错误。 - 行数计算逻辑错误:代码中列遍历使用
i <= columns作为终止条件,说明实际每一行包含columns+1个字段,但行数计算使用data.Length / columns -1,未按实际每行列数统计,会导致行数计算偏差,进一步引发数据索引错位、遗漏问题。
修复方案
- 修正字符串分割逻辑,补充
\r\n作为分隔符,同时开启空条目移除规避文件末尾空行的干扰:
string[] data = fileString.Split(new string[] { ";", "\r\n", "\n" }, StringSplitOptions.RemoveEmptyEntries);
- 统一列数计算,修正行数统计逻辑:
// 实际总列数:索引从0到columns共columns+1列 int actualColumnCount = columns + 1; // 总数据长度除以每行列数,减去1行表头得到有效数据行数 int rows = (data.Length / actualColumnCount) - 1;
- 替换所有硬编码的列偏移计算,统一使用
actualColumnCount做索引偏移,避免计算错位:
List<string> kartenvariablen = new List<string>(); for (int i = 0; i < actualColumnCount; i++) { kartenvariablen.Add(data[i]); } List<Dictionary<string, string>> allCards = new List<Dictionary<string, string>>(); for(int i=0; i< rows; i++) { Dictionary<string, string> singleCard = new Dictionary<string, string>(); for(int n= 0; n < actualColumnCount; n++) { singleCard.Add(kartenvariablen[n], data[actualColumnCount + n + (i * actualColumnCount)]); } allCards.Add(singleCard); }
内容的提问来源于stack exchange,提问作者Bealtex
相关产品推荐
相关产品推荐

