簡體   English   中英

有一個版本的StrToInt?

[英]There is an ansi version of StrToInt?

似乎StrToInt沒有Ansi重載。 這是正確的嗎? 或許我錯過了一些東西。 StrToInt堅持將我的ansistrings轉換為字符串。

你是對的。 沒有ANSI版本的StrToInt 找到ANSI版標准函數的地方是AnsiStrings單元,那里什么也沒有。

編寫自己的函數來完成工作,或者接受使用StrToInt所需的轉換。

編寫自己的函數並不難。 它可能看起來像這樣:

uses 
  SysConst; // for SInvalidInteger
....
{$OVERFLOWCHECKS OFF}
{$RANGECHECKS OFF}
function AnsiStrToInt(const s: AnsiString): Integer;

  procedure Error;
  begin
    raise EConvertError.CreateResFmt(@SInvalidInteger, [s]);
  end;

var
  Index, Len, Digit: Integer;
  Negative: Boolean;
begin
  Index := 1;
  Result := 0;
  Negative := False;
  Len := Length(s);
  while (Index <= Len) and (s[Index] = ' ') do
    inc(Index);
  if Index > Len then
    Error;
  case s[Index] of
  '-','+':
    begin
      Negative := s[Index] = '-';
      inc(Index);
      if Index > Len then
        Error;
    end;
  end;
  while Index <= Len do
  begin
    Digit := ord(s[Index]) - ord('0');
    if (Digit < 0) or (Digit > 9) then
      Error;
    Result := Result * 10 + Digit;
    if Result < 0 then
      Error;
    inc(Index);
  end;
  if Negative then
    Result := -Result;
end;

這是StrToInt中的StrToInt版本。 它不處理十六進制,並且在錯誤方面更嚴格一些。 在使用此代碼之前,我想測試這是否真的是您的瓶頸。

非常有趣的是,此代碼基於RTL源中的代碼,無法返回low(Integer) 解決這個問題並不難,但這會使代碼更加復雜。

代碼實際上非常簡單(不支持十六進制字符串,但你不需要它們):

function AnsiStrToInt(const S: RawByteString): Integer;
var
  P: PByte;
  Negative: Boolean;
  Digit: Integer;

begin
  P:= Pointer(S);
// skip leading spaces
  while (P^ = Ord(' ')) do Inc(P);
  Negative:= False;
  if (P^ = Ord('-')) then begin
    Negative:= True;
    Inc(P);
  end
  else if (P^ = Ord('+')) then Inc(P);

  if P^ = 0 then
    raise Exception.Create('No data');

  Result:= 0;
  repeat
    if Cardinal(Result) > Cardinal(High(Result) div 10) then
      raise Exception.Create('Integer overflow');
    Digit:= P^ - Ord('0');
    if (Digit < 0) or (Digit > 9) then
      raise Exception.Create('Invalid char');
    Result:= Result * 10 + Digit;
    if (Result < 0) then begin
      if not Negative or (Cardinal(Result) <> Cardinal(Low(Result))) then
        raise Exception.Create('Integer overflow');
    end;
    Inc(P);
  until (P^ = 0);
  if Negative then Result:= -Result;
end;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM