Introduction
This tip details a simple method to read CSV files.
Using the code
The main problem when reading CSV is to determine when a comma is being used to separate values from each other and when
a comma is not a separator but part of a value. The following snippet resolves this problem:
if (c == ‘,’ && quoteCount % 2 == 0)
{
}
Where variable c
is the character under consideration and quoteCount
is the running total of ‘”’
characters
in the string
at this point. Using this method it is possible to write a simple, if not robust, CSV Reader in a few lines of code.
public static List<List<string>> ReadCsv(string[] data, char separator)
{
var rows = new List<List<string>>();
foreach (string text in data)
{
int quoteCount = 0;
int startIndex = 0;
int endIndex = 0;
var cols = new List<string>();
foreach (char c in text)
{
if (c == '"')
{
quoteCount += 1;
}
else
{
if (c == separator && quoteCount % 2 == 0)
{
cols.Add(trimQuotes(text.Substring(startIndex, endIndex - startIndex)));
startIndex = endIndex + 1;
}
}
endIndex++;
}
cols.Add(trimQuotes(text.Substring(startIndex, endIndex - startIndex)));
rows.Add(cols);
}
return rows;
}
private static string trimQuotes(string text)
{
if (String.IsNullOrEmpty(text))
{
return text;
}
return text[0] == '"' && text.Length > 2
? text.Substring(1, text.Length - 2).Replace("\"\"", "\"")
: text.Replace("\"\"", "\"");
}
Conclusion
I am grateful to Jonathan Wood's excellent article, Reading and Writing CSV Files in C# , for the inspiration to write this tip. His method for parsing text into the CSV format is simply brilliant.