关于c#:String“0.080”加倍使80.00

String “0.080” to double makes 80.00

本问题已经有最佳答案,请猛点这里访问。

我在C中有这个问题,我想把一个字符串转换为double。

1
2
3
textBoxKostOnderhoud.Text ="0.08";

kost.OnderhoudKost = double.Parse(textBoxKostOnderhoud.Text);

这在我的数据库里是80.00,我不知道为什么。这个问题有什么解决办法吗?

这就是我如何将值添加到数据库(mysql)中的方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public bool insert(Kost kost)
{
    string query ="INSERT INTO kost (wagenId, onderhoudKost, tolKost, bedrijfsVerzekering, autoVerzekering, ladingVerzekering, wegenBelasting, eurovignet, accountantKost, telefoonKost, documentenEnVergunningen, onvoorzien, overige, andere) VALUES('" + kost.WagenId +"', '" + kost.OnderhoudKost +"', '" + kost.TolKost +"', '" + kost.BedrijfsVerzekering +"', '" + kost.AutoVerzekering +"', '" + kost.LadingVerzekering +"', '" + kost.WegenBelasting +"', '" + kost.Eurovignet +"', '" + kost.AccountantKost +"', '" + kost.TelefoonKost +"', '" + kost.DocumentenEnVergunningen +"', '" + kost.Onvoorzien +"', '" + kost.Overige +"', '" + kost.Andere +"')";

    if (this.OpenConnection())
    {
        //Create Command
        MySqlCommand cmd = new MySqlCommand(query, connection);
        //Create a data reader and Execute the command
        cmd.ExecuteReader();

        //close Connection
        this.CloseConnection();

        return true;
    }
    else
    {
        return false;
    }
}

SQL

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
CREATE TABLE IF NOT EXISTS `kost` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `wagenId` int(11) NOT NULL,
  `onderhoudKost` double(10,2) NOT NULL,
  `tolKost` double(10,2) NOT NULL,
  `bedrijfsVerzekering` double(10,2) NOT NULL,
  `autoVerzekering` double(10,2) NOT NULL,
  `ladingVerzekering` double(10,2) NOT NULL,
  `wegenBelasting` double(10,2) NOT NULL,
  `eurovignet` double(10,2) NOT NULL,
  `accountantKost` double(10,2) NOT NULL,
  `telefoonKost` double(10,2) NOT NULL,
  `documentenEnVergunningen` double(10,2) NOT NULL,
  `onvoorzien` double(10,2) NOT NULL,
  `overige` double(10,2) NOT NULL,
  `andere` double(10,2) NOT NULL,
  PRIMARY KEY (`id`),
  KEY `wagenId` (`wagenId`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=64 ;


我怀疑您使用的区域性的小数分隔符是","分组分隔符是"."。

可以指定分析时要使用的区域性:

1
double d = double.Parse(s, CultureInfo.InvariantCulture);

这是否合适取决于上下文,通常-字符串来自哪里?如果是用户,你知道他们的文化是什么吗?如果不是来自用户,数据源是否具有文本性质,或者是否有一种方法可以在不进行任何字符串转换的情况下获取值?

请注意,如果这是一个货币值,那么您应该使用decimal,而不是double

编辑:既然您已经包含了SQL,那么我们就可以看到为什么值不能正确地传播到数据库:

1
2
3
4
5
6
7
8
9
10
// Note properly broken, but this is all on one line. (Ick to start with.)
string query ="INSERT INTO kost (wagenId, onderhoudKost, tolKost,
   bedrijfsVerzekering, autoVerzekering, ladingVerzekering, wegenBelasting,
   eurovignet, accountantKost, telefoonKost, documentenEnVergunningen, onvoorzien,
   overige, andere) VALUES('"
+ kost.WagenId +"', '" + kost.OnderhoudKost +"', '"
   + kost.TolKost +"', '" + kost.BedrijfsVerzekering +"', '" +
   kost.AutoVerzekering +"', '" + kost.LadingVerzekering +"', '" +
   kost.WegenBelasting +"', '" + kost.Eurovignet +"', '" + kost.AccountantKost +
  "', '" + kost.TelefoonKost +"', '" + kost.DocumentenEnVergunningen +"', '" +
   kost.Onvoorzien +"', '" + kost.Overige +"', '" + kost.Andere +"')";

您正在将所有值转换为SQL中的字符串,并希望您的数据库将以相同的方式再次解析它们。事实上,由于您的默认文化,它不会再次出现。

更重要的是,这里有一个巨大的SQL注入攻击漏洞。

不要这样做。使用参数化SQL,在SQL中放置占位符,然后分别指定参数值。好处:

  • 防止SQL注入攻击
  • 通过将代码(SQL)与数据分离,可以使SQL语句更清晰。
  • 减少你最终要做的转换次数,这样你就少了担心文化等问题的地方。

请参阅用于参数精确格式的mysql驱动程序的文档(我相信根据驱动程序的不同,可能会有一些稍微不同的格式)-但从根本上讲,这是应用于所有数据库访问的内容,无论您正在与哪个数据库交谈,也无论您使用什么语言。


您可以在double.Parse中使用CultureInfo.InvariantCulture来忽略当前的文化:

1
double d = double.Parse(s, CultureInfo.InvariantCulture);

演示

1
2
output:
0.08


由于您要连接字符串以创建SQL命令文本,所以您的double d可能会转换为字符串"0080",MySQL可能会将其解释为80。