AnsiString to Double C ++

时间:2017-12-30 14:22:22

标签: c++builder ansistring

我正在尝试将AnsiString转换为double,但在运行该程序后,它表示" 20.60不是有效的浮点数"。

AnsiString Temperatur

RE_Temperatur->Text = Temperatur;

Chart1->Series[0]->AddXY(DT_Uhrzeit->Time, RE_Temperatur->Text.ToDouble(), 
"", clRed);

Temperatur的值来自我的Arduino的SerialPort连接,并提供类似20.60等等。当我将字符串剪切到前2位数时,它工作正常。猜猜.与错误有关,但我不知道如何解决它。

编辑// 我现在试图替换"。"与","使用以下代码:

    RE_Temperatur->Text = StringReplace(RE_Temperatur->Text, ".", ",", 
    TReplaceFlags() << rfReplaceAll);

现在我收到错误消息&#34; 20,60不是有效的浮点&#34;。它太令人沮丧了:/

3 个答案:

答案 0 :(得分:2)

您可以使用StrToFloat它的第二个版本带有TFormatSettings对象,您可以使用该对象指定特定的DecimalSeperator。顺便说一下,它没有返回一个浮点数,因为它的名字可能暗示它返回一个Extended又名long double

答案 1 :(得分:2)

在新的控制台程序中尝试这段简单的代码:

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

答案 2 :(得分:0)

我敢打赌,你的问题是小数点。用于它的字符是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部分我正在使用它来处理任何类型的数字......