-1

When converting a user input (string) to an Integer and it goes wrong, I want to know if that is because the number represented by the string exceeded integer limitations (eg. was larger than 2147483647) or if the string contained letters that were unconvertible (like 'abc.-').

I already tried catching the Exception and looking into it, but there is no meaningful information.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
MeroFuruya
  • 20
  • 5
  • 1
    Which actual code did you use? Delphi doesn't know only one way to convert texts to numbers. [`Val()`](https://docwiki.embarcadero.com/Libraries/Sydney/en/System.Val) will at least tell you the erroneous position. – AmigoJack Dec 14 '22 at 10:54
  • @AmigoJack i used [`StrToInt()`](https://docwiki.embarcadero.com/Libraries/Alexandria/en/System.SysUtils.StrToInt). Gotta try [`Val()`](https://docwiki.embarcadero.com/Libraries/Sydney/en/System.Val) tho. ty – MeroFuruya Dec 14 '22 at 11:08
  • Edit your question to include actual code - we still not know HOW you used `StrToInt()` and with WHICH data. While editing your post you could also fix the many typos you made. – AmigoJack Dec 14 '22 at 11:10
  • I could actually just iterate through the string. if there is any char that is not in `['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-']` i know why the fail is caused. if there is no `'-'` in the string and it then fails i know the number is too big, if there is a `'-'` i know it is too small. if it passes, obveously everything is fine anyways so. didnt thought about this early enougth tho – MeroFuruya Dec 14 '22 at 11:14
  • Delphi knows [ranges](https://docwiki.embarcadero.com/RADStudio/Sydney/en/Structured_Types_(Delphi)#Sets): `['0'.. '9', '-']` is the same. – AmigoJack Dec 14 '22 at 11:17
  • good call.. gonna use a range :) – MeroFuruya Dec 14 '22 at 11:22
  • Use `function TryStrToInt(const S: string; out Value: Integer): Boolean;` If the function is successful, the result is in the Value parameter. – USauter Dec 14 '22 at 13:10
  • @USauter but this doesnt tell me why the conversion failed in case it did fail.. and thats what i need – MeroFuruya Dec 14 '22 at 13:42
  • You can use .toInteger to get the value. Please be noticed that AnsiString was deprecated in Alexandria with Android compiler. If you used AnsiString, RawByteString to cast the string, and the platform is Android, the result of casted string will be empty string. – Dennies Chang Dec 27 '22 at 09:49

1 Answers1

-2

So this is what i've come up with now (i edited the answer bc it was kinda bad before):

unit BetterStrToInt;

interface

uses
  System.SysUtils, System.SysConst;

type
  EStrToIntOverflowTooBig = class(EConvertError);
  EStrToIntOverflowTooSmall = class(EConvertError);
  EStrToIntBadChar = class(EConvertError);

function BStrToInt(const s: string): integer;

implementation

function BStrToInt(const s: string): integer;
var
  e: integer;
begin
  Val(s, Result, e);
  if e <> 0 then
    if s = '-' then
      raise EStrToIntBadChar.CreateFmt(SInvalidInteger, ['-'])
    else
      if CharInSet(s[e], ['0' .. '9']) then
        if s.StartsWith('-') then
          raise EStrToIntOverflowTooSmall.Create(SIntOverflow)
        else
          raise EStrToIntOverflowTooBig.Create(SIntOverflow)
      else
        raise EStrToIntBadChar.CreateFmt(SInvalidInteger, [s[e]]);
end;

end.

the if s = '-' then is needed becaus when s = '-' Val() sets e to 2. Then s[e] in if CharInSet(s[e], ['0' .. '9']) then creates an Index Error. That behavior is unwanted (imo atleast).

maybe there is a better solution but i dont know any atm.

MeroFuruya
  • 20
  • 5
  • This doesn't account for `'-'` as input, since it won't raise any exception. And there's no need for `for c in xs` because `e` already holds the position of `s` where the problematic character is found - why not directly using `s[e]`? – AmigoJack Dec 14 '22 at 13:42
  • huh? it only removes the minus it its at the first position (e.g. `-123`) and so doesnt raise an exception. when the minus is anywhere in the string but in the first place (e.g. `1-23` or `123-`) it should raise an exception.. – MeroFuruya Dec 14 '22 at 13:45
  • Read again: what about the "number" `'-'` (without any more characters)? A string of length 1 with only the minus? – AmigoJack Dec 14 '22 at 13:47
  • oh damn ur right.... – MeroFuruya Dec 14 '22 at 14:00
  • okay. I updated the answer. Now it doesnt use the uneccesary for loop. It also accounted for `s` being `'-'`. hope this is better :) i could also move the `if s = '-' then` to the top so in that case `Val()` wouldnt even need to be executed. but im not sure if that helps understanding what happens there. – MeroFuruya Dec 14 '22 at 14:34
  • Test it with `2147483648` (preferably enable range checking first). – BrakNicku Dec 14 '22 at 15:02
  • 1
    Use TryStrToInt and don't worry about diagnosing it for the user. Just tell them it must be a number in a specific range. Trust the user not to be stupid. – David Heffernan Dec 14 '22 at 15:55