【问题标题】:CSV to 2D array but Split function throws a NullPointerExceptionCSV 到 2D 数组,但 Split 函数抛出 NullPointerException
【发布时间】:2017-01-23 09:40:10
【问题描述】:

我试图通过循环并将 CSV 放入二维数组。

由于var tokens = sr.ReadLine().Split(',');,我的应用程序崩溃它抛出了 NullPointerException。我该如何解决这个问题?

下面是我的整个方法,名为 csvToArray

public string[,] csvToArray (string filePath)
        {
            int col = colCount(filePath);
            int row = rowCount(filePath);
            string line;

            string[,] data = new string[col, row];

            using (StreamReader sr = new StreamReader(filePath))
            {
                for (int i = 0; i < col; i++)
                {
                    var tokens = sr.ReadLine().Split(',');

                    for (int j = 0; j < row; j++)
                    {

                        data[i, j] = tokens[j];
                    }
                }
            }
            return data;
        }

没有意义的是它完成了整个循环。异常下的变量具有它们应该具有的值

【问题讨论】:

  • 我认为循环的行和列应该交换
  • 尝试在var tokens = sr.ReadLine().Split(','); 之前添加一个简单的if (sr != null) 检查。或者可选var line = sr.ReadLine()if (sr != null &amp;&amp; !string.IsNullOrWhiteSpace(line))
  • @KeyurPATEL 我的 CSV 文件有空白值。这会导致拆分问题吗?
  • 如果有任何空白值,这将确保您不会抛出异常。此外,由于异常发生在拆分行上,我认为这是由于您尝试拆分空白值。在任何情况下,if 条件都会对您有所帮助。

标签: c# .net csv multidimensional-array webforms


【解决方案1】:

让我们首先分析示例中的错误。

1) 为什么在开始时需要知道行和列的长度?这是开销。

2) 循环中的行和列无效。

3) 在您的示例中抛出此异常,因为您已达到 EOF。

所以,这是将 csv 读取为 2D 矩阵的更好方法:

public int[][] csvToArray (string filePath)
        {
            string line = null;
            var result = new List<int[]>();
            using (var sr = new StreamReader(filePath))
            {
                while((line = sr.ReadLine()) != null)
                {
                    if(string.IsNullOrWhiteSpace(line)) continue;
                    result.Add(sr.Split(',').Select(x=> string.IsNullOrWhiteSpace(x) ? 0 : int.Parse(x)).ToArray());
                }
            }
            return result.ToArray();
        }

然后您可以检查矩阵的一致性。 至少,这样您就不会打开文件三次并避免计数错误。

【讨论】:

  • 如何在空值中插入“0”?这样之后的任务会更容易,即获取每列的平均值。
【解决方案2】:

您必须首先使用for 循环循环,然后使用内循环循环。

public static string[,] csvToArray(string filePath)
    {
        int col = colCount(filePath);
        int row = rowCount(filePath);
        string line;

        string[,] data = new string[row, col];

        using (StreamReader sr = new StreamReader(filePath))
        {
            for (int i = 0; i < row; i++)
            {
                var tokens = sr.ReadLine().Split(',');

                for (int j = 0; j < col; j++)
                {

                    data[i, j] = tokens[j];
                }
            }
        }
        return data;
    }

在你的代码中你正在做null.Split(),这就是它给你异常的原因。

如果你想在每个单元格中插入0作为一个空白行,那么你可以实现下面的代码。

for (int i = 0; i < row; i++)
            {
                string content = sr.ReadLine();
                if (!string.IsNullOrEmpty(content))
                {
                    var tokens = content.Split(',');

                    for (int j = 0; j < col; j++)
                    {

                        data[i, j] = tokens[j];
                    }
                }
                else
                {
                    for (int j = 0; j < col; j++)
                    {

                        data[i, j] = "0";
                    }
                }
            }

【讨论】:

  • 我也检查过,但filePath 确实正确且有效。我想知道为什么srNULL
  • U 必须有一个空行。那么如果你在 CSV 中有空行,你想要什么?你想在二维数组中插入一个空白数组,还是只想忽略那行?
  • 如何为空行插入“0”?我必须对它之后的所有列进行平均,因此在空白处插入“0”是有意义的。
  • 我根据你的评论开始实施:P
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-08-07
  • 1970-01-01
  • 2011-12-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-24
相关资源
最近更新 更多