22
votes

Is there a method in Delphi to check if a string is a number without raising an exception?

its for int parsing.

and an exception will raise if one use the

try
  StrToInt(s);
except
  //exception handling
end;
10
What is "infinite exceptions"? - David Heffernan
By number you mean integer? Or do you want to allow real numbers as well? - jpfollenius
Is the number in the string required to be a number that can be stored by a Delphi numeric type? Nineteen quintillion is a number, but it won't fit in any Delphi integral type. One hundred-thousandth is a number, but no Delphi numeric type can hold it. - Rob Kennedy
@Rob Kennedy: if Application.MessageBox('Is this a number?'#13#10+str, MB_YESNO + MB_ICONQUESTION + MB_DEFBUTTON1) = IdYes then ShowMessage(str +' IS a number!') else ShowMessage('Sorry. ''+str+'' doesn't seem to be a number...'); - Jørn E. Angeltveit
@Jørn, it was a serious question. I'm just trying to stave off the embarrassment of displaying a nonsense error message like "19000000000000000 is not a number." - Rob Kennedy

10 Answers

27
votes
var
  s: String;
  iValue, iCode: Integer;
...
val(s, iValue, iCode);
if iCode = 0 then
  ShowMessage('s has a number')
else
  ShowMessage('s has not a number');
66
votes

function TryStrToInt(const S: string; out Value: Integer): Boolean;

TryStrToInt converts the string S, which represents an integer-type number in either decimal or hexadecimal notation, into a number, which is assigned to Value. If S does not represent a valid number, TryStrToInt returns false; otherwise TryStrToInt returns true.

To accept decimal but not hexadecimal values in the input string, you may use code like this:

function TryDecimalStrToInt( const S: string; out Value: Integer): Boolean;
begin
   result := ( pos( '$', S ) = 0 ) and TryStrToInt( S, Value );
end;
18
votes

Try this function StrToIntDef()

From help

Converts a string that represents an integer (decimal or hex notation) to a number with error default.

Pascal

function StrToIntDef(const S: string; Default: Integer): Integer;

Edit

Just now checked the source of TryStrToInt() function in Delphi 2007. If Delphi 7 dont have this function you can write like this. Its just a polished code to da-soft answer

function TryStrToInt(const S: string; out Value: Integer): Boolean;
var
  E: Integer;
begin
  Val(S, Value, E);
  Result := E = 0;
end;
7
votes

XE4 and newer:

for ch in s do
   TCharacter.IsNumber(ch);

Don't forget:

uses System.Character    
3
votes

In delphi 7 you can use the Val procedure. From the help:

Unit: System Delphi syntax: procedure Val(S; var V; var Code: Integer);

S is a string-type expression; it must be a sequence of characters that form a signed real number.

V is an integer-type or real-type variable. If V is an integer-type variable, S must form a whole number.

Code is a variable of type Integer.

If the string is invalid, the index of the offending character is stored in Code; otherwise, Code is set to zero. For a null-terminated string, the error position returned in Code is one larger than the actual zero-based index of the character in error.

3
votes

use this function

function IsNumber(N : String) : Boolean;
var
I : Integer;
begin
Result := True;
if Trim(N) = '' then
 Exit(False);

if (Length(Trim(N)) > 1) and (Trim(N)[1] = '0') then
Exit(False);

for I := 1 to Length(N) do
begin
 if not (N[I] in ['0'..'9']) then
  begin
   Result := False;
   Break;
 end;
end;

end;

2
votes

For older Delphi versions from delphi 5 help example:

uses Dialogs;
var 

  I, Code: Integer;
begin
  { Get text from TEdit control }
  Val(Edit1.Text, I, Code);
  { Error during conversion to integer? }
  if Code <> 0 then
    MessageDlg('Error at position: ' + IntToStr(Code), mtWarning, [mbOk], 0);
  else
    Canvas.TextOut(10, 10, 'Value = ' + IntToStr(I));   
end;
1
votes

In some languages decimal separators are different (for example, '.' is used in English and ',' is used in Russian). For these cases to convert string to real number the following procedure is proposed:

function TryStrToFloatMultiLang(const S : String; out Value : Extended) : Boolean;
var
  dc : char;
begin
  Result := false;
  dc := DecimalSeparator;
  DecimalSeparator := '.';
  try
    Result := TryStrToFloat(S, Value);
  except
    DecimalSeparator := ',';
    Result := TryStrToFloat(S, Value);
  end;
  DecimalSeparator := dc;
end;

Update

As @Pep mentioned TryStrToFloat catch exceptions, but it returns boolean value. So the correct code is:

function TryStrToFloatMultiLang(const S : String; out Value : Extended) : Boolean;
var
  dc : char;
begin
  Result := false;
  dc := DecimalSeparator;
  DecimalSeparator := '.';
  Result := TryStrToFloat(S, Value);
  if not Result then begin
    DecimalSeparator := ',';
    Result := TryStrToFloat(S, Value);
  end;
  DecimalSeparator := dc;
end;
0
votes

When you using procedure

val(s, i, iCode);

and set value xd ....

val('xd', i, iCode)

as a result we obtain: 13

-2
votes

standard unit Variants

function VarIsNumeric(v:Variant):Boolean