Convert string with commas to float

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.

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);

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;

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");

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;

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;

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

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;

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;
    }

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;
    }

procedure Edit1Exit(Sender: TObject);

begin

edit1.Text:=stringreplace(edit1.Text,””,”,[rfReplaceAll]);
if not IsValidDecimal( maskedit1.Text ) then
begin
showmessage(‘The Decimal entered -> ‘+edit1.Text+’ <- is in the wrong format ‘);
edit1.SetFocus;
end;
end;

function IsValidDecimal(S:string):boolean;

VAR

FS: TFormatSettings;
DC: variant;
begin

//FS := TFormatSettings.Create(‘it-IT’);
FS := TFormatSettings.Create(‘en-EN’);
try
DC:=StrToFloat ( S, FS );
result:=true;
except
on e:exception do
result:=false;
end;

end;

Leave a Comment