Convert string with commas to float

こ雲淡風輕ζ 提交于 2019-12-05 17:42:52

问题


Is there a built-in Delphi function which would convert a string such as '3,232.00' to float? StrToFloat raises an exception because of the comma. Or is the only way to strip out the comma first and then do StrToFloat?

Thanks.


回答1:


Do you exactly know, that '.' is decimal separator and ',' is thousand separator (always)? If so, then you should fill the TFormatSettings record and pass it to StrToFloat.

FillChar(FS, SizeOf(FS), 0);
... // filling other fields
FS.ThousandSeparator := ',';
FS.DecimalSeparator := '.';
V := StrToFloat(S, FS);



回答2:


below is what i use. there might be more efficient ways, but this works for me. in short, no, i don't know of any built-in delphi function that will convert a string-float containing commas to a float

{~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  safeFloat

  Strips many bad characters from a string and returns it as a double.
}
function safeFloat(sStringFloat : AnsiString) : double;
var
  dReturn : double;

begin
  sStringFloat := stringReplace(sStringFloat, '%', '', [rfIgnoreCase, rfReplaceAll]);
  sStringFloat := stringReplace(sStringFloat, '$', '', [rfIgnoreCase, rfReplaceAll]);
  sStringFloat := stringReplace(sStringFloat, ' ', '', [rfIgnoreCase, rfReplaceAll]);
  sStringFloat := stringReplace(sStringFloat, ',', '', [rfIgnoreCase, rfReplaceAll]);
  try
    dReturn := strToFloat(sStringFloat);
  except
    dReturn := 0;
  end;
  result := dReturn;

end;



回答3:


Try: StrToFloat(StringReplace('3,232.00', ',', '') It should get rid of the commas before doing the conversion.

In C# / VB.NET I use would use something like decimal.convert("3,232.00", ",", "");

I know of no way to do the conversion without stripping out the extra characters. In fact, I have a special function in my library that strips out commas and currency symbols. So a actually call MyConverer.decimalConverter("$3,232.00");




回答4:


function StrToFloat_Universal( pText : string ): Extended;
const
   EUROPEAN_ST = ',';
   AMERICAN_ST = '.';
var
  lformatSettings : TFormatSettings;
  lFinalValue     : string;
  lAmStDecimalPos : integer;
  lIndx           : Byte;
  lIsAmerican     : Boolean;
  lIsEuropean     : Boolean;

begin
  lIsAmerican := False;
  lIsEuropean := False;
  for lIndx := Length( pText ) - 1 downto 0 do
  begin
    if ( pText[ lIndx ] = AMERICAN_ST ) then
    begin
      lIsAmerican := True;
      pText := StringReplace( pText, ',', '', [ rfIgnoreCase, rfReplaceAll ]);  //get rid of thousand incidental separators
      Break;
    end;
    if ( pText[ lIndx ] = EUROPEAN_ST ) then
    begin
      lIsEuropean := True;
      pText := StringReplace( pText, '.', '', [ rfIgnoreCase, rfReplaceAll ]);  //get rid of thousand incidental separators
      Break;
    end;
  end;
  GetLocaleFormatSettings( LOCALE_SYSTEM_DEFAULT, lformatSettings );
  if ( lformatSettings.DecimalSeparator = EUROPEAN_ST ) then
  begin
    if lIsAmerican then
    begin
      lFinalValue := StringReplace( pText, '.', ',', [ rfIgnoreCase, rfReplaceAll ] );
    end;
  end;
  if ( lformatSettings.DecimalSeparator = AMERICAN_ST ) then
  begin
    if lIsEuropean then
    begin
      lFinalValue := StringReplace( pText, ',', '.', [ rfIgnoreCase, rfReplaceAll ] );
    end;
  end;
  pText  := lFinalValue;
  Result := StrToFloat( pText, lformatSettings );
end;



回答5:


I use a function which is able to handle the ',' and the '.' as decimalseparator...:

function ConvertToFloat(aNr: String; aDefault:Integer): Extended;
var
  sNr, s3R, sWhole, sCent:String;
  eRC:Extended;
begin
  sNr:=ReplaceStr(sNr, ' ', '');

  if (Pos('.', sNr) > 0) or (Pos(',', sNr) > 0) then
  begin
    // Get 3rd character from right
    s3R:=LeftStr(RightStr(sNr, 3), 1);
    if s3R <> DecimalSeparator then
    begin
      if not IsNumber(s3R) then
      begin
        s3R := DecimalSeparator;
        sWhole := LeftSr(sNr, Length(sNr) - 3);
        sCent := (RightStr(sNr, 2);
        sNr := sWhole + DecimalSeparator + sCent;
      end
      else
        // there are no decimals... add ',00'
        sNr:=sNr + DecimalSeparator + '00';
    end;
    // DecimalSeparator is present; get rid of other symbols
    if (DecimalSeparator = '.') and (Pos(',', sNr) > 0) then sNr:=ReplaceStr(sNr, ',', '');
    if (DecimalSeparator = ',') and (Pos('.', sNr) > 0) then sNr:=ReplaceStr(sNr, '.', '');
  end;

  eRc := StrToFloat(sNr);
end;



回答6:


I had the same problem when my Users need to enter 'scientific' values such as "1,234.06mV". Here there is a comma, a multiplier (m=x0.001) and a unit (V). I created a 'wide' format converter routine to handle these situtations. Brian




回答7:


Myfunction:

function StrIsFloat2 (S: string;  out Res: Extended): Boolean;
var
  I, PosDecimal: Integer;
  Ch: Char;
  STrunc: string;
  liDots, liComma, J: Byte;
begin
  Result := False;
  if  S = ''
  then  Exit;
  liDots := 0;
  liComma := 0;
  for  I := 1 to Length(S)  do  begin
    Ch := S[I];
    if  Ch = FormatSettings.DecimalSeparator  then  begin
      Inc (liDots);
      if  liDots > 1  then  begin
        Exit;
      end;
    end
    else if  (Ch = '-') and (I > 1) then  begin
      Exit;
    end
    else if Ch = FormatSettings.ThousandSeparator then begin
      Inc (liComma);
    end
    else if not CharIsCipher(Ch) then  begin
      Exit;
    end;
  end;
  if liComma > 0 then begin
    PosDecimal := Pos (FormatSettings.DecimalSeparator, S);
    if PosDecimal = 0 then
      STrunc := S
    else
      STrunc := Copy (S, 1, PosDecimal-1);
    if STrunc[1] = '-' then
      Delete (S, 1, 1);
    if Length(STrunc) < ((liComma * 3) + 2) then
      Exit;
    J := 0;
    for I := Length(STrunc) downto 1 do begin
      Inc(J);
      if J mod 4 = 0 then
        if STrunc[I] <> FormatSettings.ThousandSeparator then
          Exit;
    end;
    S := ReplaceStr (S, FormatSettings.ThousandSeparator, '');
  end;
  try
    Res := StrToFloat (S);
    Result := True;
  except
    Result := False;
  end;
end;



回答8:


Using Foreach loop

 public static float[] ToFloatArray()
    {
     string pcords="200.812, 551.154, 232.145, 482.318, 272.497, 511.752";

      float[] spiltfloat = new float[pcords.Split(',').Length];
        int i = 0;
        foreach (string s in pcords.Split(','))
        {
           spiltfloat[i] = (float)(Convert.ToDouble(s));
            i++;
        }
        return spiltfloat;
    }



回答9:


using lemda Expression to convert string comma seprated to float array

public static float[] ToFloatArrayUsingLemda()
    {
        string pcords="200.812, 551.154, 232.145, 482.318, 272.497, 511.752";
        float[] spiltfloat = new float[pcords.Split(',').Length];

        string[] str = pcords.Split(',').Select(x => x.Trim()).ToArray();

        spiltfloat = Array.ConvertAll(str, float.Parse);
        return spiltfloat;
    }


来源:https://stackoverflow.com/questions/788098/convert-string-with-commas-to-float

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!