У меня есть DLL C#, которая уже использует CsvHelper для чтения файлов CSV. Итак, мне было интересно, есть ли у CsvHelper возможность просто передать ему string (не файл), и он вернет список токенов?
Настолько, что:
2023/11/06,Name,PartType,""Эй, это тема!"",1
становится списком:
В итоге я выбрал этот метод С#, основываясь на некоторых других ответах и комментариях ниже:
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;
}
Соответствующая оболочка C++:
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;
}
Но когда я запускаю свой код, например:
theApp.MSAToolsInterface().ParseCSVText(5, lineText, strDelimiter, listFields)
и зайдите в отладку, HRESULT C# говорит, что файл не найден. Нет файла - это строка. 🧐
@Ralf Спасибо, но у меня проблемы. Пожалуйста, посмотрите мой обновленный вопрос.
StreamReader принимает путь к файлу как строку, а не строку для ее непосредственного анализа. Измените StreamReader на StringReader.
@Ralf Теперь прекрасно работаю! Спасибо.
Что не так с string.Split
@Charlieface может string.Split справиться не только с разделителями, но и с квалификаторами текста?





Вот последний метод:
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;
}
Конструктор CsvReader из CsvHelper принимает TextReader, поэтому источником строки может быть что угодно. Вот просто возьмите StringReader.