我正在用c#编写一个程序,遇到了一个烦人的小问题。我需要将字段从dataGridView控件转换为double,以便将它们存储在数据库中。但是,它无法正确转换。
dataGridView中的原始值使用逗号(,)进行小数点分隔。
这是原始代码:
double number = Convert.ToDouble(dataGridView1.Rows[row].Cells[1].Value)
单元格是文本框类型。通过使用该方法,12,3变为12,3E + 14
由于某些未知原因,转换器将数字乘以10乘以功率14。
在阅读了一些问题之后,我偶然发现了另一种可能的解决方案
double number = Convert.ToDouble(dataGridView1.Rows[row].Cells[1].Value, CultureInfo.CurrentCulture);
结果仍然相同。 12,3 - > 12,3E + 14
double number = Convert.ToDouble(dataGridView1.Rows[row].Cells[1].Value.ToString(), CultureInfo.CurrentCulture);
这变得更有趣。而不是12,3我得到了123
我错过了什么吗?对所有这些都有一个简单的解决方案吗?
编辑:以防万一 - 数据库字段类型设置为real,dataGridView单元格是TextBox类型,因此输入是字符串类型。
EDIT2:我要做的是将值(实际)从数据库加载到DGV,将其保存到不同的数据库表中,然后从新写入的数据库表(实际)加载值并显示它在另一个DGV。将值从DGV1写入数据库后,其类型为Single。然而,在第二次将它们写入数据库之后,该值变为String类型,即使我没有对它进行任何更改。这可能是扭曲转换价值的原因吗?我的意思是他们第一次出现在12,3E + 14而不是12,3。我可以用Math.Pow(10,14)来划分它们以获得原始值,但这是肮脏的做法:/
最终编辑:谢谢大家的帮助,但在这种情况下真正的问题是我的疏忽。 由于这个程序正在开发很长一段时间,当我还习惯了c#语法时,我已经包含了一些变量类型的混淆,这使我不得不检查代码中的所有类型。再次,谢谢大家的帮助。
TL; DR - 保持变量类型一致。
答案 0 :(得分:2)
如果你的CurrentCulture是在美国,它会将“1,23”解析为123.
正如Tigran所说,创建一个FormatProvider,或者创建一个NumberFormatInfo。如果您不想/需要更改CurrentCulture默认值,这是一个替代解决方案。
NumberFormatInfo provider = new NumberFormatInfo();
provider.NumberDecimalSeparator = ",";
double num = Convert.ToDouble("1,23", provider);
如果这行代码为您提供123:
double number = Convert.ToDouble(dataGridView1.Rows[row].Cells[1].Value.ToString(), CultureInfo.CurrentCulture);
那么这应该给你1.23:
NumberFormatInfo provider = new NumberFormatInfo();
provider.NumberDecimalSeparator = ",";
double number = Convert.ToDouble(dataGridView1.Rows[row]
.Cells[1].Value.ToString(),provider);
答案 1 :(得分:0)
您可以尝试使用a来调用要替换的字符串上的replace函数。然后进行转换。试试这个:
double number = Convert.ToDouble(dataGridView1.Rows[row].Cells[1].Value.ToString().Replace(",", "."));
答案 2 :(得分:0)
你试试吗
double da = double.Parse(a,CultureInfo.InvariantCulture);
这里有类似的问题
他们用它
答案 3 :(得分:0)
第一个和第二个案例是相同的,因为在两种情况下,函数都使用CurrentCulture
,就像第二个参数一样。
第三个更有趣,因为您使用:Convert.ToDouble(String)重载,它使用
哪个可能推迟你的那台机器。当前线程文化的格式约定。
所以首先要做的事情就是imo,你可以检查一下当前的调试(我想象一下)线程文化是否等于你的那台机器,如果不是那会产生影响。
考虑在“fr-FR”中,小数分隔符为“,”,其中“en-US”为“。”。 为了正确威胁已知的数据格式,您需要提供自定义FormatProvider并使用它进行解析。
因此,在您的情况下,代码可能如下所示:
//assign expected separator
NumberFormatInfo nf = new NumberFormatInfo();
nf.NumberDecimalSeparator = ",";
var val = dataGridView1.Rows[row].Cells[1].Value;
double number = Convert.ToDouble(val, nf);
应该适合你。
答案 4 :(得分:0)
由于Value
属性的类型为object
,因此它可能包含一个盒装双值。在这种情况下,演员就足够了:
double number = (double)dataGridView1.Rows[row].Cells[1].Value;
或者,如果列可以为空,可能
double? number = (double?)dataGridView1.Rows[row].Cells[1].Value;
请注意,这不涉及转换,只是将值转换为正确的类型。
尝试输出此信息以了解值的类型:
System.Diagnostics.Debug.WriteLine(
dataGridView1.Rows[row].Cells[1].Value.GetType().Name);
然后打开输出窗口。
答案 5 :(得分:0)
我终于解决了我的问题。看来,即使C#具有本地化选项,SQL也没有。
数字转换得很好,但SQL解析查询错误:
"INSERT INTO myTable VALUES ('2,5' , '3,1');
没有用,但是这样做了:
"INSERT INTO myTable VALUES ('2.5' , '3.1');