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(),但如果您希望它使用用户区域设置的小数点分隔符,请不要使用它。