AnsiString 到 Double C++
AnsiString to Double C++
我正在尝试将 AnsiString
转换为 double
,但是在 运行 程序之后,它说“20.60 不是有效的浮点数”。
AnsiString Temperatur
RE_Temperatur->Text = Temperatur;
Chart1->Series[0]->AddXY(DT_Uhrzeit->Time, RE_Temperatur->Text.ToDouble(),
"", clRed);
Temperatur
的值来自我的 Arduino 的串行端口连接,并提供类似 20.60 等的值。当我将字符串剪切到前 2 位数字时,它工作正常。猜想 .
与错误有关,但我不知道如何解决它。
编辑//
我现在尝试只替换“。”带有“,”和以下代码:
RE_Temperatur->Text = StringReplace(RE_Temperatur->Text, ".", ",",
TReplaceFlags() << rfReplaceAll);
现在我收到一条错误消息“20,60 不是有效的浮点数”。太令人沮丧了:/
您可以使用 StrToFloat 它有第二个版本,它采用 TFormatSettings
对象,您可以使用该对象指定特定的 DecimalSeperator
。顺便说一句,它不是 return 浮点数,正如它的名字所暗示的那样 return 是一个 Extended
又名 long double
.
我敢打赌你的问题是小数点。用于它的字符是 Windows 环境变量之一,并且可能因计算机而异。有 winapi 调用来接收它,但我不记得了......
AnsiString("1.23").ToDouble()
的问题是 catch/try
不会捕获异常(至少在我的编译器 BDS2006 上是这样)。有解决方法。我正在使用 atoi()
而不是崩溃,而是在存在无效字符时截断为整数,因此它可用于检测正确的小数点字符和转换:
char _floating_point_char=' '; // decimal point separator
AnsiString strnum (AnsiString s,int sig=1,int pnt=1,int hex=0,char dot=_floating_point_char);
double str2num(AnsiString s,int sig=1,int pnt=1,int hex=0,char dot=_floating_point_char);
AnsiString strnum(AnsiString s,int sig,int pnt,int hex,char dot)
{
if (dot==' ')
{
float x;
x=atof("0.5"); if (x>=0.25) _floating_point_char='.';
x=atof("0,5"); if (x>=0.25) _floating_point_char=',';
dot=_floating_point_char;
}
int i,l,a,e,e0,exp=pnt;
AnsiString q="";
l=s.Length();
if (hex) exp=0; // exponent is e,E so it colide with hex e,E
e0=0; for (i=1;i<=l;i++)
{
e=0;
a=s[i];
if ((a>='0')&&(a<='9')) { e=1; q+=char(a ); sig=0; }
if ((a>='A')&&(a<='F'&&(hex))){ e=1; q+=char(a ); sig=0; }
if ((a>='a')&&(a<='f'&&(hex))){ e=1; q+=char(a ); sig=0; }
if ((a=='e')||(a=='E'))
if (!hex) { if (!exp) break; e=1; q+=char('e'); exp=0; sig=1; pnt=0; e0=0; }
if (a=='+') { if (!sig) break; e=1; sig=0; }
if (a=='-') { if (!sig) break; e=1; q+=char(a ); sig=0; }
if (a=='.') { if (!pnt) break; e=1; q+=char(dot); pnt=0; }
if (a==',') { if (!pnt) break; e=1; q+=char(dot); pnt=0; }
if ((e0)&&(!e)) break;
e0|=e;
}
if (q.Length()<=0) q="0";
return q;
}
double str2num(AnsiString s,int sig,int pnt,int hex,char dot)
{
return atof(strnum(s,sig,pnt,hex,dot).c_str());
}
它只是检测 .
或 ,
是否正确,然后在转换前将其替换为字符串...从 winapi 粗略获取正确的小数点字符 更安全,因为小数点分隔符可以是任何东西...您可以忽略 hex
部分我将其用于任何类型的数字...
在新的控制台程序中尝试这段简单的代码:
AnsiString Temperatur = "12.45"; // locale independent
AnsiString Temperatur2 = "12,45"; // correct in my German locale
double temp = StrToFloat(Temperatur, TFormatSettings::Invariant());
double temp2 = StrToFloat(Temperatur2); // In my case: German locale!
printf("%8.4f %8.4f\n", temp, temp2);
输出为:
12.4500 12.4500
您可以看到它按预期工作。请注意,在我的系统上,逗号 是区域设置的小数点分隔符,但是由于格式设置不变,此代码可以很好地使用句点作为小数点分隔符。
因此请做出您的选择:如果您需要区域设置的独立性,请使用 TFormatSettings::Invariant()
,但如果您希望它使用用户区域设置的小数点分隔符,请不要使用它。
我正在尝试将 AnsiString
转换为 double
,但是在 运行 程序之后,它说“20.60 不是有效的浮点数”。
AnsiString Temperatur
RE_Temperatur->Text = Temperatur;
Chart1->Series[0]->AddXY(DT_Uhrzeit->Time, RE_Temperatur->Text.ToDouble(),
"", clRed);
Temperatur
的值来自我的 Arduino 的串行端口连接,并提供类似 20.60 等的值。当我将字符串剪切到前 2 位数字时,它工作正常。猜想 .
与错误有关,但我不知道如何解决它。
编辑// 我现在尝试只替换“。”带有“,”和以下代码:
RE_Temperatur->Text = StringReplace(RE_Temperatur->Text, ".", ",",
TReplaceFlags() << rfReplaceAll);
现在我收到一条错误消息“20,60 不是有效的浮点数”。太令人沮丧了:/
您可以使用 StrToFloat 它有第二个版本,它采用 TFormatSettings
对象,您可以使用该对象指定特定的 DecimalSeperator
。顺便说一句,它不是 return 浮点数,正如它的名字所暗示的那样 return 是一个 Extended
又名 long double
.
我敢打赌你的问题是小数点。用于它的字符是 Windows 环境变量之一,并且可能因计算机而异。有 winapi 调用来接收它,但我不记得了......
AnsiString("1.23").ToDouble()
的问题是 catch/try
不会捕获异常(至少在我的编译器 BDS2006 上是这样)。有解决方法。我正在使用 atoi()
而不是崩溃,而是在存在无效字符时截断为整数,因此它可用于检测正确的小数点字符和转换:
char _floating_point_char=' '; // decimal point separator
AnsiString strnum (AnsiString s,int sig=1,int pnt=1,int hex=0,char dot=_floating_point_char);
double str2num(AnsiString s,int sig=1,int pnt=1,int hex=0,char dot=_floating_point_char);
AnsiString strnum(AnsiString s,int sig,int pnt,int hex,char dot)
{
if (dot==' ')
{
float x;
x=atof("0.5"); if (x>=0.25) _floating_point_char='.';
x=atof("0,5"); if (x>=0.25) _floating_point_char=',';
dot=_floating_point_char;
}
int i,l,a,e,e0,exp=pnt;
AnsiString q="";
l=s.Length();
if (hex) exp=0; // exponent is e,E so it colide with hex e,E
e0=0; for (i=1;i<=l;i++)
{
e=0;
a=s[i];
if ((a>='0')&&(a<='9')) { e=1; q+=char(a ); sig=0; }
if ((a>='A')&&(a<='F'&&(hex))){ e=1; q+=char(a ); sig=0; }
if ((a>='a')&&(a<='f'&&(hex))){ e=1; q+=char(a ); sig=0; }
if ((a=='e')||(a=='E'))
if (!hex) { if (!exp) break; e=1; q+=char('e'); exp=0; sig=1; pnt=0; e0=0; }
if (a=='+') { if (!sig) break; e=1; sig=0; }
if (a=='-') { if (!sig) break; e=1; q+=char(a ); sig=0; }
if (a=='.') { if (!pnt) break; e=1; q+=char(dot); pnt=0; }
if (a==',') { if (!pnt) break; e=1; q+=char(dot); pnt=0; }
if ((e0)&&(!e)) break;
e0|=e;
}
if (q.Length()<=0) q="0";
return q;
}
double str2num(AnsiString s,int sig,int pnt,int hex,char dot)
{
return atof(strnum(s,sig,pnt,hex,dot).c_str());
}
它只是检测 .
或 ,
是否正确,然后在转换前将其替换为字符串...从 winapi 粗略获取正确的小数点字符 更安全,因为小数点分隔符可以是任何东西...您可以忽略 hex
部分我将其用于任何类型的数字...
在新的控制台程序中尝试这段简单的代码:
AnsiString Temperatur = "12.45"; // locale independent
AnsiString Temperatur2 = "12,45"; // correct in my German locale
double temp = StrToFloat(Temperatur, TFormatSettings::Invariant());
double temp2 = StrToFloat(Temperatur2); // In my case: German locale!
printf("%8.4f %8.4f\n", temp, temp2);
输出为:
12.4500 12.4500
您可以看到它按预期工作。请注意,在我的系统上,逗号 是区域设置的小数点分隔符,但是由于格式设置不变,此代码可以很好地使用句点作为小数点分隔符。
因此请做出您的选择:如果您需要区域设置的独立性,请使用 TFormatSettings::Invariant()
,但如果您希望它使用用户区域设置的小数点分隔符,请不要使用它。