tags:

views:

437

answers:

7

Hello,

I'm trying to figure out a way to check a string's first element if it's either a number or not.

if not(myString[0] in [0..9]) then //Do something

The problem is that I get an error "Element 0 inaccessible - use 'Length' or 'SetLength"

Another way came to my head from my C-like exprieince - convert the first element of the string to char and check the char,but there is no difference in the compile errors.

if not(char(myString[0]) in [0..9]) then //Do something

How do I accomplish it?

+10  A: 

Strings are 1-based:

if not (myString[1] in ['0'..'9']) then // Do something
TOndrej
47 seconds... damn... ;)
Oliver Giesen
Just one problem now "incompatible types - string and integer". If I use StrToInt and the string isn't an integer then an exception will be thrown and all that check is useless.Could you suggest a better way? +1 by the way. :)
John
John, use TryStrToInt then.
Pauk
Look again at TOndrej's code: There should be single-quotes around the '0'..'9'
Oliver Giesen
Good point Oliver, shows how much attention I was paying.
Pauk
+6  A: 

Delphi strings use a 1-based index, so just rewrite to

if not(myString[1] in ['0'..'9']) then //Do something

Also take note of the quotes around the 0..9, otherwise you would be comparing characters to integers.

Oliver Giesen
+7  A: 

Pascal and Delphi indexes string from 1. This is a legacy from time where zero byte contained length, while next 255 (index 1 to 255) contained actual characters. Joel Spolsky wrote quite good article on string issues:
http://www.joelonsoftware.com/articles/fog0000000319.html

smok1
+1 for explaining *why* they're 1-based
Oliver Giesen
The "Spolsky" article talks about implementing Pascal strings in C without any compiler support. The problems are irrelevant for languages that have support for it.
Marco van de Voort
@Marco van de Voort: I am afraid you completely missed the point of Joel’s article.
smok1
A: 

if not(myString[0] in [0..9]) then //Do something

If you're using Delphi 2009, the TCharacter class in Character.pas has functions like IsDigit to help simplify these kinds of operations.

Once you fix the indexing, of course. :)

Bruce McGee
The cast to Char() isn't necessary, as a string is made up of chars and they can be accessed directly. Also, your comparison would be wrong anyway, as Char('0') is decimal 48 (hex 30), and therefore wouldn't fall between 0 and 9.
Ken White
A: 

The simplest way to check to see if the first character of string is an integer, and then dispatch:

var
  iResult : integer;
begin
  if TryStrToInt( mySTring[1], iResult) then
    begin
      // handle number logic here iResult = number
    end
  else
    begin
      // handle non number logic here
    end;
end;
skamradt
No, I don't think that's the simplest way at all. John actually had the right idea, but was fumbling around in the dark for the proper syntax.
Rob Kennedy
True, but if you wanted to act on the value then it required using StrtoInt. If you use TryStrToInt you not only can check to see if its a number, you then have the number to then use.
skamradt
A: 

I use a utility function to test the entire string:

function IsNumeric(const Value: string): Boolean;
var
  i: Integer;
begin
  Result := True;
  for i := 1 to Length(Value) do
    if not (Value[i] in ['0'..'9','.','+','-']) then
    begin
      Result := False;
      Break;
    end;
end;

The above code is for Delphi versions prior to 2007. In 2007 and 2009, you could change the integer variable i to a character c, and use for c in Value instead.

To test for integers only, remove the '.' from the set of characters to test against.

Ken White
A: 

This is incorrect. ISO strings and older Pascal's also started at one. It is just a general convention, and afaik the s[0] thing is a result of that being vacant, and cheap to code in the UCSD bytecode interpreter. But that last bit is before my time, so only my guessing.

It results from the Pascal ability to have arbitrary upper and lower bounds, which provides for more typesafety accessing arrays.

Really old Pascal strings (till early eighties) strings were even worse than C ones btw. Multiple conventions were in used, but all were based on static arrays (like early C), but they were typically space padded, so you had scan back from the end till the spaces ended.

(removed the legacy tag, since being 1 based is not legacy. Accessing s[0] as length IS legacy, but that is not what the question is about)

Marco van de Voort