【问题标题】:string format error when reading CSVs to object with LINQ使用 LINQ 将 CSV 读取到对象时出现字符串格式错误
【发布时间】:2019-01-23 10:08:36
【问题描述】:

我正在将 CVS 文件中的数据读入 C# 列表对象。我只能读取字符串值。当我尝试读取一个数值(在这种情况下为双精度值)时,我得到输入字符串格式不正确的异常。任何人都可以显示 我如何克服这个? 这是代码:

类:

 public class Loan
    {
        string applicationDT;
        string employeeID;
        string employeeName;
        double amount;
        string lonType;

        public void printLoan()
        {
            Console.WriteLine($" employeeName {employeeName} employee Id {employeeID}" +
                $"applicationDate {applicationDT} \namount {amount} loanType {lonType}");
        }

        public static Loan fromCVS(string csvLine)
        {
            string []values = csvLine.Split(',');
            Loan loanRecord = new Loan();
            loanRecord.employeeName = (values[3]);
            loanRecord.employeeID = (values[4]);
            loanRecord.applicationDT = (values[5]);
            loanRecord.amount = Convert.ToDouble(values[6]);
            loanRecord.lonType = (values[7]);
            return loanRecord;
        }
    }

主要:

static void Main()
{
    List<Loan> loans = File.ReadAllLines(@"C:\Users\0300Test.csv")
                                   .Skip(1)
                                   .Select(v => Loan.fromCVS(v))
                                   .ToList();
    foreach(Loan aLoan in loans)
    {
        aLoan.printLoan();
    }
}

CSV 文件:

"APPROVAL_OFFICER_NAME","APPROVAL_OFFICER_ID","RELATIONSHIP_MANAGER_NAME","EMPLOYEE_NAME","EMPLOYEE_ID","APPLICATION_DATE_TIME","AMOUNT","TYPE_OF_LOAN"
"SAMPLNAME","988803","SAMPLNAME","SAMPLNAME","776667","1/22/2019 11:05:43 AM","321146.00","Top Up With Settlement"
"SAMPLNAME","988803","SAMPLNAME","SAMPLNAME","776667","1/22/2019 9:34:13 AM","90230.00","Top Up With Settlement"
"SAMPLNAME","988803","SAMPLNAME","SAMPLNAME","776667","1/22/2019 12:00:22 AM","5230.00","Top Up without Settlement"

【问题讨论】:

  • 请编辑您的问题并添加失败的数据示例(来自 csv 文件)
  • 编辑了问题
  • 假设您的 csv 没有任何“这对我有用,没有任何异常。您是否调试过哪个值引发了异常?

标签: c# linq csv double


【解决方案1】:

显然你的问题是当你想给amount赋值时

string []values = csvLine.Split(',');
double amount = Convert.ToDouble(values[6]);

你当然调试了代码。您认为values[6] 的价值是什么?

从您的 csv 行示例看来,类似于:"\"90230.00\""

所以它是一个以字符串引号开头和结尾的字符串。无法将此值转换为双精度值。

解决方法很简单:去掉这个值开头和结尾的字符串引号。

  amount = Double.Parse(value[6].SubString(1, value[6].Length-2));

顺便说一句,您希望employeeName(和所有其他人)成为字符串 SAMPLENAME 还是应该用引号括起来:“SAMPLENAME”(所以在内部是“\”SAMPLENAME\“”)?

如果您想从所有值中删除这些开始和结束字符串引号,请考虑为字符串创建扩展函数。见extension methods demystified

public static IEnumerable<string> SplitAndRemoveQuotes(this string string)
{
    // TODO: handle null string
    var splitValues = string.Split(',');
    foreach(string splitValue in splitValues)
    {
         // if you are certain every split value starts and ends with string quote
         // TODO: throw exception if not start/end with string quote?
         yield return splitValue.SubString(1, splitValue.Length-2);
    }
}

因此,如果您的字符串格式为 "\"\"\"",(可读格式:""")返回值将是一个只有一个引号 (") 的字符串

用法:

public static Loan fromCVS(string csvLine)
{
    // TODO: exception if csvLine null or empty

    var splitWithoutQuotes = csvLine.SplitAndRemoveQuotes()
        .Skip(2)        // we don't need the first two values
        .Take(5)        // we only need the next five values
        .ToList();
    // TODO: exception if result not 5 items

    return new Loan
    {
        employeNames = splitWithoutQuotes[0],
        ...
        amount = Double.Parse(values[4]);
        ...
    };
}

【讨论】:

  • 感谢您的澄清。至于 employeeName ,我在发布之前更改了数据
  • 你能告诉我如何根据文件中的格式读取日期和时间吗?
  • 要将字符串转换为日期时间:使用DateTime.ParseDateTime.ParseExact。通常ParseConvert 更好
【解决方案2】:

如果您查看数据

"SAMPLNAME","988803","SAMPLNAME","SAMPLNAME","776667","1/22/2019 11:05:43 AM","321146.00","充值结算"

每个参数都用引号括起来。

values[6] 的值实际上是 "321146.00",并被 " 包围,因此无法转换。

 var x = values[6].Replace("\"", string.Empty);

【讨论】:

  • 如果我想在以后的文件中避免引号 - 单引号或双引号 - 有没有办法做到这一点?
  • 可能不会。我不建议从完整文件中删除所有引号,因为它们可以在某个地方的字符串中使用。 “充值'与'结算”可能是有效的。您应该只在日期和数字字段上替换它们。在将这些字段转换为之前,您不希望在其中看到任何引号。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-29
  • 1970-01-01
  • 2017-08-01
相关资源
最近更新 更多