I have a C# DLL which already uses CsvHelper
to read CSV files. So I was wondering if CsvHelper
has the capacity for me to simply pass it a string
(not a file) and it return the list of tokens?
So much so, that:
2023/11/06,Name,PartType,"“Hey, This is the Theme!”",1
becomes a list:
I have ended up with this C# method, based on some other answers and the comments below:
public int ParseCSVText(string textToParse, string delimiter, out string[] tokens)
{
List<string> listTokens = new List<string>();
using (var stringReader = new StreamReader(textToParse))
{
var config = new CsvConfiguration(CultureInfo.InvariantCulture);
config.Delimiter = delimiter;
config.HasHeaderRecord = false;
using (var reader = new CsvReader(stringReader, config))
{
while (reader.Read())
{
listTokens.Add(reader.GetField(0));
listTokens.Add(reader.GetField(1));
listTokens.Add(reader.GetField(2));
listTokens.Add(reader.GetField(3));
listTokens.Add(reader.GetField(4));
}
}
}
tokens = listTokens.ToArray();
return listTokens.Count;
}
The associated C++ wrapper:
bool CMSATools::ParseCSVText(const int fieldCount, const CString textToParse, const CString delimiter, CStringArray& listTokens)
{
SAFEARRAY* saTokens = nullptr;
if (m_pInterface != nullptr)
{
long count{};
const auto hr = m_pInterface->ParseCSVText(textToParse.AllocSysString(), delimiter.AllocSysString(), &saTokens, &count);
if (SUCCEEDED(hr))
ConvertSAFEARRAY<BSTR, CStringArray>(saTokens, listTokens);
else
throw_if_fail(hr);
}
return listTokens.GetSize() == fieldCount;
}
But when I run my code, eg:
theApp.MSAToolsInterface().ParseCSVText(5, lineText, strDelimiter, listFields)
and go into debug the HRESULT
of the C# is saying the file can't be found. There is no file - it is a string. 🧐
Here is the final method:
public int ParseCSVText(string textToParse, string delimiter, out string[] tokens)
{
List<string> listTokens = new List<string>();
try
{
using (var stringReader = new StringReader(textToParse))
{
var config = new CsvConfiguration(CultureInfo.InvariantCulture);
config.Delimiter = delimiter;
config.HasHeaderRecord = false;
using (var reader = new CsvReader(stringReader, config))
{
while (reader.Read())
{
for (int column = 0; column < reader.ColumnCount; column++)
{
listTokens.Add(reader.GetField(column));
}
}
}
}
}
catch (Exception ex)
{
SimpleLog.Log(ex);
}
tokens = listTokens.ToArray();
return listTokens.Count;
}