输入字符串格式不正确,但不知道原因

时间:2014-05-09 11:07:21

标签: c# mysql string-formatting

在我的C#应用​​程序中,我正在从MySQL表中读取数字数据。之后,我正在寻找一个最小的欧几里德距离(表格行和平均元组之间)。

我正在将MySQL表中的值读入双变量(f1f8和一个int变量)。我在第一行上收到此错误,我将读者的结果放入f1。但是,当我在读取我的值(例如f1 + f8)后进行随机计算时,它会返回正确/精确的结果。那么为什么C#输入字符串有问题呢?

这是我的代码:

for (int k = 1; k <= pocet; k++)
{
    string queryCompare = " SELECT F1 AS Fe1, F2 AS Fe2, F3 AS Fe3, F4 AS Fe4, F5 AS Fe5, F6 AS Fe6, F7 AS Fe7, F8 AS Fe8, cluster FROM features WHERE ID=" + k;
    MySqlCommand cmdCompare = new MySqlCommand(queryCompare, conect);
    readerCompare = cmdCompare.ExecuteReader();
    readerCompare.Read();
    //  MessageBox.Show("OK");
    double f1 = Convert.ToDouble(readerCompare["Fe1"].ToString());  // EXCEPTION HERE
    double f2 = Convert.ToDouble(readerCompare["Fe2"].ToString());
    double f3 = Convert.ToDouble(readerCompare["Fe3"].ToString());
    double f4 = Convert.ToDouble(readerCompare["Fe4"].ToString());
    double f5 = Convert.ToDouble(readerCompare["Fe5"].ToString());
    double f6 = Convert.ToDouble(readerCompare["Fe6"].ToString());
    double f7 = Convert.ToDouble(readerCompare["Fe7"].ToString());
    string f88 = readerCompare["Fe8"].ToString();
    double f8 = Convert.ToDouble(f88, CultureInfo.InvariantCulture);
    int cluster = Convert.ToInt32(readerCompare["cluster"].ToString());

    readerCompare.Close();
    //  MessageBox.Show((f1+f8).ToString());

    switch (cluster)
    {
        case 1:
            euklDist = (double)Math.Sqrt(
                                        Math.Pow(touple[0, 0] - f1, 2) + 
                                        Math.Pow(touple[0, 1] - f2, 2) + 
                                        Math.Pow(touple[0, 2] - f3, 2) + 
                                        Math.Pow(touple[0, 3] - f4, 2) + 
                                        Math.Pow(touple[0, 4] - f5, 2) + 
                                        Math.Pow(touple[0, 5] - f6, 2) + 
                                        Math.Pow(touple[0, 6] - f7, 2) + 
                                        Math.Pow(touple[0, 7] - f8, 2));

            if (euklDist < minCl1)
            {
                minCl1 = euklDist;
                idCl1 = k;
            }
            break;

        case 2:
            euklDist = (double)Math.Sqrt(
                                        Math.Pow(touple[1, 0] - f1, 2) +
                                        Math.Pow(touple[1, 1] - f2, 2) +
                                        Math.Pow(touple[1, 2] - f3, 2) + 
                                        Math.Pow(touple[1, 3] - f4, 2) + 
                                        Math.Pow(touple[1, 4] - f5, 2) +
                                        Math.Pow(touple[1, 5] - f6, 2) +
                                        Math.Pow(touple[1, 6] - f7, 2) +
                                        Math.Pow(touple[1, 7] - f8, 2));

            if (euklDist < minCl2)
            {
                minCl2 = euklDist;
                idCl2 = k;
            }
            break;

        case 3:
            euklDist = (double)Math.Sqrt(
                                        Math.Pow(touple[2, 0] - f1, 2) +
                                        Math.Pow(touple[2, 1] - f2, 2) + 
                                        Math.Pow(touple[2, 2] - f3, 2) +
                                        Math.Pow(touple[2, 3] - f4, 2) +
                                        Math.Pow(touple[2, 4] - f5, 2) + 
                                        Math.Pow(touple[2, 5] - f6, 2) + 
                                        Math.Pow(touple[2, 6] - f7, 2) + 
                                        Math.Pow(touple[2, 7] - f8, 2));

            if (euklDist < minCl3)
            {
                minCl3 = euklDist;
                idCl3 = k;
            }
            break;
    }
}

我的数据库中的记录采用以下格式:

  • 从f1到f7:xx,xxx
  • f8:xx.xxx

我知道f8有小数点而不是逗号,这就是为CultureInfo.InvariantCulture使用f8的原因。

1 个答案:

答案 0 :(得分:3)

您无需更新 null值,只需执行以下操作:

Convert.ToDouble(readerCompare["Fe1"]);

null将由ToDouble处理,并将其转换为默认值; 0

请参阅以下代码中使用的ToDouble实现:

public static double ToDouble(object value)
{
  if (value != null)
    return ((IConvertible) value).ToDouble((IFormatProvider) null);
  else
    return 0.0;
}

更新:好吧如果您还需要支持空字符串,那么您必须稍微更改此代码。首先让我们构建一个扩展方法。在解决方案中创建一个新的class,并将其命名为SystemExtensions,然后粘贴此代码:

namespace System
{
    public static class SystemExtensions
    {
        public static string ToConvertibleDouble(this object input)
        {
            var s = input as string;
            if (string.IsNullOrEmpty(s.Trim())) { return null; }

            // this will also take care of the separator
            return s.Replace(".", ",");
        }
    }
}

现在让我们使用它:

Convert.ToDouble(readerCompare["Fe1"].ToConvertibleDouble());
Convert.ToDouble(readerCompare["Fe2"].ToConvertibleDouble());
...
Convert.ToDouble(readerCompare["Fe8"].ToConvertibleDouble());