1

I have a .csv file that looks like this:

Index,Time,value
1,0,20
2,1,30

What I want to do is to open the .csv file in C# and then read it by getting row = 0, column = 0 which would give me value 1 in the case above. Much like this:

public double GetVal(int row, int column)
{
 ...
 return val;
}

I have looked around for a solution, for example this one: Remove values from rows under specific columns in csv file

But I need to be able to specify both the column and row in the function to get the specific value.

KGB91
  • 630
  • 2
  • 6
  • 24
  • 2
    Take a 3r party library https://joshclose.github.io/CsvHelper/examples/reading/get-class-records. then you will have a list object where you can nagivate using index and property name. Really more usefull that row and column. And read the file only once. – Drag and Drop Mar 04 '20 at 09:52
  • There's actually a CSV parser in .Net natively; the `TextFieldParser` in the `VisualBasic` namespace. – Nyerguds Mar 04 '20 at 13:49

3 Answers3

2

In case CSV file is simple one (no quotations), you can try Linq:

using System.IO;
using System.Linq;

...

public double GetVal(int row, int column) {
  return File
    .ReadLines(@"c:\MyFile.csv") //TODO: put the right name here
    .Where(line => !string.IsNullOrWhiteSpace(line)) // to be on the safe side
    .Skip(1)   // Skip line with Titles
    .Skip(row)
    .Select(line => double.Parse(line.Split(',')[column]))
    .First();
}

Note, that this code re-reads the file; you may want to read the file once:

  string[][] m_Data = File
    .ReadLines(@"c:\MyFile.csv")
    .Where(line => !string.IsNullOrWhiteSpace(line)) 
    .Skip(1)
    .Select(line => line.Split(','))
    .ToArray();

  ...

  public double GetVal(int row, int column) => double.Parse(m_Data[row][col]);
Dmitry Bychenko
  • 180,369
  • 20
  • 160
  • 215
  • I tested the latter one and it gives me "System.FormatException: 'Input string was not in a correct format.'". – KGB91 Mar 04 '20 at 13:42
  • @KGB91: `System.FormatException` is thrown when `string` doesn't meet expected format, e.g. when we `double.Parse` on a `string` which can't be converted into `double` (`"abcdef"` and alike) – Dmitry Bychenko Mar 04 '20 at 13:44
  • Can't I just everything as a string and then convert it to a double if I want to? – KGB91 Mar 04 '20 at 13:58
  • @KGB91: yes, we can postpone `double.Parse` which we can perform at `GetVal` – Dmitry Bychenko Mar 04 '20 at 14:01
0

Although you can write simple code by yourself, I would suggest you using dedicated CSV library for this like https://www.nuget.org/packages/LumenWorksCsvReader/ There are tons of edge cases like values escaping with double quotes, multiline values in CSV file format.

But if you totally control your files and they are small, you can read all lines at once and parse them. Something like this to get all lines from file and then split every line by ',' character

var lines = File.ReadAllLines('your file');
dlxeon
  • 1,932
  • 1
  • 11
  • 14
0

Quick answer, without considering the performance issue (e.g. the file read should happen once, and other issue like index checking to avoid overflows.

public double GetVal(int row, int column) 
{
    double output;
    using (var reader = new StreamReader("filename.csv"))
    {
        int m = 1;
        while (!reader.EndOfStream)
        {
            if(m==row)
            {
                var splits = rd.ReadLine().Split(',');
                //You need check the index to avoid overflow
                output = double.Parse(splits[column]);
                return output;
            }

            m++;
        }
    }
    return output;
}
David
  • 15,894
  • 22
  • 55
  • 66