问题
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