我需要编写一个CSV解析器我现在正试图分离字段来操纵它们。
示例CSV: mitarbeiter ^ ^ tagesdatum ^ lohnart ^ kostenstelle ^ kostentraeger ^猛恶^ betrag belegnummer 11005 ^ 2018年1月23日^ 1 ^^ 31810020 ^ 5,00 ^ ^ 11081 ^ 2018年1月23日^ 1 ^^ 31810020 ^ 5,00 ^ ^
如您所见,有几个空单元格。
我正在做以下事情:
using (CsvFileReader reader = new CsvFileReader(path))
{
CsvRow row = new CsvRow();
while (reader.ReadRow(row))
{
foreach (string s in row)
{
csvROW.Add(new aCSVROW());
string[] items = s.Split(new char[] { '^' }, StringSplitOptions.None);
csvROW[0].mitarbeiter = items[0];
csvROW[0].tagesdatum = items[1];
csvROW[0].lohnart = items[2];
csvROW[0].kostenstelle = items[3];
csvROW[0].kostentraeger = items[4];
csvROW[0].menge = items[5];
csvROW[0].betrag = items[6];
csvROW[0].belegnummer = items[7];
}
}
}
问题:
似乎Split在逗号后停止(5,00)。分隔符是^ ...有原因吗? 我尝试了几件事没有成功......
非常感谢你!
答案 0 :(得分:2)
CsvFileReader
从CSV文件中读取行,然后读取该行中的字符串。你期望CsvFileReader
做什么比分开行?
阅读第二行后,row
将包含内容
11005^23.01.2018^1^^31810020^5
和
00^^
当您将第一行分割为^
时,结果数组的最后一个条目将为"5"
。无论如何,你的代码会抛出,因为你试图访问超出数组范围的项目。
我不知道CsvFileReader
。也许你可以将^
作为分隔符传递,并且不需要拆分字符串。无论如何,你也可以使用StreamReader
。这将更像您的期望。
using (StreamReader reader = new StreamReader(path))
{
while (!reader.EndOfStream)
{
var csvLine = reader.ReadLine();
csvROW.Add(new aCSVROW());
string[] items = csvLine.Split(new char[] { '^' }, StringSplitOptions.None);
csvROW[0].mitarbeiter = items[0];
csvROW[0].tagesdatum = items[1];
csvROW[0].lohnart = items[2];
csvROW[0].kostenstelle = items[3];
csvROW[0].kostentraeger = items[4];
csvROW[0].menge = items[5];
csvROW[0].betrag = items[6];
csvROW[0].belegnummer = items[7];
}
}
答案 1 :(得分:0)
CsvRow
是所有行还是一个行的数据?因为实际上,您不断为每个读取行添加一个新的aCSVROW
对象到csvROW
,但是您继续只更换csvROW [0]上的数据,首先插入aCSVROW
。这意味着最终,你将拥有许多行,除了索引0上的那些行之外,它们都没有数据,每次迭代都会覆盖它的属性,最后包含最后一行的数据
此外,尽管使用了CsvReader
类,但您使用普通法线String.Split
来实际分隔字段。当然这就是CsvReader
班级的用途?
就个人而言,我总是使用TextFieldParser
命名空间中的Microsoft.VisualBasic.FileIO
。它具有在.Net框架中完全原生的优点,您可以简单地告诉它使用哪个分隔符。
此函数可以将数据从简单List<String[]>
:
A: Using C# to search a CSV file and pull the value in the column next to it
获得数据后,您可以根据需要将其粘贴到对象中。
List<String[]> lines = SplitFile(path, textEncoding, "^");
// I assume "CsvRow" is some kind of container for multiple rows?
// Looks like pretty bad naming to me...
CsvRow allRows = new CsvRow();
foreach (String items in lines)
{
// Create new object, and add it to list.
aCSVROW row = new aCSVROW();
csvROW.Add(row);
// Fill the actual newly created object, not the first object in allRows.
// conside adding index checks here though to avoid index out of range exceptions.
row.mitarbeiter = items[0];
row.tagesdatum = items[1];
row.lohnart = items[2];
row.kostenstelle = items[3];
row.kostentraeger = items[4];
row.menge = items[5];
row.betrag = items[6];
row.belegnummer = items[7];
}
// Done. All rows added to allRows.
答案 2 :(得分:-2)
CsvRow row = new CsvRow();
while (reader.ReadRow(row))
{
foreach (string s in row)
{
csvROW.Add(new aCSVROW());
s.Split("^","");
csvROW[0].mitarbeiter = items[0];
csvROW[0].tagesdatum = items[1];
csvROW[0].lohnart = items[2];
csvROW[0].kostenstelle = items[3];
csvROW[0].kostentraeger = items[4];
csvROW[0].menge = items[5];
csvROW[0].betrag = items[6];
csvROW[0].belegnummer = items[7];
}
}
}