views:

251

answers:

2

In a sorting routine in Delphi 2007 I am using code like this:

(txt[n] in ['0'..'9'])

function ExtractNr(n: Integer; var txt: String): Int64;  
begin  
  while (n <= Length(txt)) and (txt[n] in ['0'..'9']) do n:= n + 1;  
  Result:= StrToInt64Def(Copy(txt, 1, (n - 1)), 0);  
  Delete(txt, 1, (n - 1));  
end;  

where txt is a string. This works fine in D2007 but will give warnings in D2009 and D2010 I have no idea why but is there any way I can make it work without warnings in D2009 and D2010?

Roy M Klever

+9  A: 

use CharInSet or better use Character.IsDigit

François
+8  A: 

Are you getting the "WideChar reduced to byte Char in set expressions. Consider using 'CharInSet' function in 'SysUtils' unit" message?

Here's the issue. In D2009, the default string type was changed from AnsiString to UnicodeString. An AnsiString uses a single byte for each character, giving you 256 possible characters. A UnicodeString uses 2 bytes per character, giving up to 64K characters. But a Pascal set can only contain up to 256 elements. So it can't create a "set of WideChar" because there are too many possible elements.

The warning is a warning that you're attempting to compare txt[n], which is a WideChar from a Unicode string, against a set of chars. It can't make a set of WideChars, so it had to reduce them to AnsiChars to fit them into a Pascal set, and your txt[n] might be outside the Ansi boundaries entirely.

You can fix it by using CharInSet, or by making txt an AnsiString, if you're certain you won't need any Unicode characters for it. Or if that won't work well, you can disable the warning, but I'd consider that a last resort.

Mason Wheeler
Thank you for nice explanation, I get it now and was able to avoid the warnings by using (txt[n] >= '0') and (txt[n] <= '9')Roy M Klever
Roy M Klever
I always disable the warning because the compiler generates perfectly valid code for "WideChar in AnsiCharSet". And because I know that all my characters are ASCII characters < #128, I see no need to slow down a tight loop with the "inlined" CharInSet() function. This may have to do with the fact that I love fast and resource friendly code.
Andreas Hausladen

related questions