0

I'm having trouble creating the 2-d array "smartdata" from my CSV file data "smart eye data.csv". I keep getting errors stating "Object reference not set to an instance of an object".

I know that 2 for loops will be necessary to create the outer and inner dimensions of the matrix, but still haven't got this to work. The CSV data is just a spreadsheet of numbers. Any help would be greatly appreciated. Thanks

using (StreamReader oStreamReader = new StreamReader(File.OpenRead("Smart Eye data.csv")))
    {
        sFileContents = oStreamReader.ReadToEnd();
    }

    string[][] smartdata = new string[1000][]; 

    string[] sFileLines = sFileContents.Split(Environment.NewLine.ToCharArray(), StringSplitOptions.RemoveEmptyEntries);

    int i = 0;

    foreach(string sFileline in sFileLines)
    {
        string[] rowarray = sFileline.Split(",".ToCharArray(),StringSplitOptions.RemoveEmptyEntries);


        for (int j = 0; j < rowarray.Length; j++)
        {

            smartdata[i][j] =rowarray[j]; //where the error occurs
            //Debug.Log(smartdata[i][j]);

                }
        i = i + 1 ;
    }
jazb
  • 5,498
  • 6
  • 37
  • 44
TDillon97
  • 13
  • 2
  • 2
    `Split` is not your friend here, use a dedicated library – TheGeneral Jan 04 '19 at 00:05
  • csvhelper library is what you need to read csv files https://joshclose.github.io/CsvHelper/ – pm100 Jan 04 '19 at 00:08
  • Which line of code gives the error? – Chetan Jan 04 '19 at 00:08
  • Q: Could you show an example as to how this .csv file is formatted? – paulsm4 Jan 04 '19 at 00:08
  • Hi, the error occurs on the line: smartdata[i][j] =rowarray[j]; – TDillon97 Jan 04 '19 at 00:09
  • 1
    the problem is that you have not allocated the inner array. Better to use a list of lists – pm100 Jan 04 '19 at 00:10
  • The CSV file is just a simple list of numbers: column elements separated by commas, and row elements separated by "\n": -1.555893994,-1.683177191,65535 43846,137909,8166605099, – TDillon97 Jan 04 '19 at 00:15
  • How would I go about allocating the inner array? – TDillon97 Jan 04 '19 at 00:17
  • What you're using here is a jagged array. A 2D array would look like `new string[,]` or `new string[1000,10]`, the first dimension being the rows and the second being the columns. Regardless, to define the second dimension even in a jagged array (which is really just a series of nested 1D arrays of varying size), you need to know how many rows and columns. Assuming your CSV is uniformly generated, you could simply split the first row at `,` and using the length as the second dimension. – oscilatingcretin Jan 04 '19 at 00:25

3 Answers3

0

if you insist on using a 2d array (I would not) you simply need (and insist on not using csvhelper)

   foreach(string sFileline in sFileLines)
    {

 smartdata[i] = sFileline.Split(",".ToCharArray(),StringSplitOptions.RemoveEmptyEntries);
}

if you want to do it the hard way then do this

    for (int j = 0; j < rowarray.Length; j++)
    {
        smartdata[i] = new string[rowarray.Length];
        smartdata[i][j] =rowarray[j]; //where the error occurs
        //Debug.Log(smartdata[i][j]);

            }
    i = i + 1 ;

Now you can see what my original comment meant. I a jagged array(what you have ) you have to allocate each row.

pm100
  • 48,078
  • 23
  • 82
  • 145
  • Thanks a lot, would smartdata not be a 1-dimensional array in that case though? I'm trying to get a 2-d array (i.e. smartdata[i][j]) if possible. – TDillon97 Jan 04 '19 at 00:21
  • you are assigning the array returned by split to the ith entry in your array. So you end up with a 2d array – pm100 Jan 04 '19 at 00:26
  • @TDillon97 smartdata[i,j]? https://stackoverflow.com/questions/597720/what-are-the-differences-between-a-multidimensional-array-and-an-array-of-arrays – Leo Bartkus Jan 04 '19 at 00:27
  • no, smartdata[i][j] will work fine. Do you want smartdata[i,j] thats quite a different thing?. Really you should use a list of lists – pm100 Jan 04 '19 at 00:29
  • does my extra edit make it clear whats happeing? The result of both bits of code is that same, the second way just does it very inefficiently – pm100 Jan 04 '19 at 00:33
  • I think I get where you are coming from in that the 2 array is basically a combination of multiple row arrays, but what I really want to be able to do later on in the code is refer to any element from the data CSV using two indices (say 'a' and 'b'). I'm not sure how to do that when the output is smartdata[i] (even if that is more efficient) – TDillon97 Jan 04 '19 at 00:42
0

pm100 gave you the real problem: you're not allocating your inner array; hence the error.

Using a CSV library isn't a bad idea - but it certainly isn't a necessity.

Using lists (instead of arrays) has the benefit that you don't need to know the #/rows or #/columns in advance.

Here's an example:

List<List<string>> mylist = new List<List<string>>();
using (StreamReader sr = new StreamReader(File.OpenRead("Smart Eye data.csv")))
{
   string line;
   while((line = sr.ReadLine()) != null)  
   {  
      System.Console.WriteLine(line);  
      List<string>row = line.Split(",").ToList();
      mylist.Add(row);
   }
}
...
paulsm4
  • 114,292
  • 17
  • 138
  • 190
  • you dont know that csvhelper is not necessary, there could by ',' characters in the input data – pm100 Jan 04 '19 at 00:28
0

You should initialize child array of 2d array:

foreach(string sFileline in sFileLines)
{
  string[] rowarray = sFileline.Split(",".ToCharArray(),StringSplitOptions.RemoveEmptyEntries);

    smartdata[i]=new string[rowarray.Length];
    for (int j = 0; j < rowarray.Length; j++)
    {

        smartdata[i][j] =rowarray[j]; //where the error occurs
        //Debug.Log(smartdata[i][j]);

    }
    i = i + 1 ;
}
paulsm4
  • 114,292
  • 17
  • 138
  • 190
Taoph
  • 44
  • 2