Results 1 to 7 of 7

Thread: Access Violation while trying to make a FloatInStr Function.

  1. #1
    Join Date
    May 2008
    Location
    Canada
    Posts
    665
    Mentioned
    0 Post(s)
    Quoted
    7 Post(s)

    Default Access Violation while trying to make a FloatInStr Function.

    Was compiling exactly this, and i'm getting: Error: Access violation at line 27.
    What's happening?

    Code looks ugly, was playing around trying different things to get it working >.<.

    Simba Code:
    program FloatInStr;
      var
    i: integer;
    j: integer;
    txt: String;
    tmpInt: Integer;
    dotFound: Boolean;
    newInt: array of Integer;
    breakit:Boolean;
    begin
      txt := 'lo 21.3da';
      j := 0;
      dotFound := false;
      breakit := false;

      for i := 1 to Length(txt) do
      begin
        tmpInt := ord(txt[i]);
        writeln(tmpInt);

        if (tmpInt >= 48) then
        begin
          if (tmpInt <= 57) then
          begin
            //while (tmpInt >= 48 and tmpInt <= 57 or tmpInt = 46 and dotFound = false) do
            repeat
              newInt[j] := ord(txt[i+j]);
              writeln('rwr ' + inttostr(j));
              j := j +1;
            until (j >= 4 and j>5 );
            breakit := true;
          end;
        end;

        if breakit then
          break;

               {
        if (txt[i] == '1' or txt[i] =='2' or txt[i] =='3' or txt[i] =='4' or txt[i] =='5' or txt[i] =='6' or txt[i] =='7' or txt[i] =='8' or txt[i] =='9' or txt[i] =='0') then
        begin
          while (txt[i+j] = '1' or txt[i+j] ='2' or txt[i+j] ='3' or txt[i+j] ='4' or txt[i+j] ='5' or txt[i+j] ='6' or txt[i+j] ='7' or txt[i+j] ='8' or txt[i+j] ='9' or txt[i+j] ='0' or txt[i+j] ='.') do
            newTxt[j] := txt[i];
        end;
              }

      end;

    end.
    Last edited by mrpickle; 02-25-2017 at 03:37 AM.

  2. #2
    Join Date
    Jan 2012
    Posts
    2,568
    Mentioned
    35 Post(s)
    Quoted
    356 Post(s)

    Default

    You need to expand the array by using SetLength(newInt, someNewLength).

  3. #3
    Join Date
    Feb 2012
    Location
    Norway
    Posts
    995
    Mentioned
    145 Post(s)
    Quoted
    596 Post(s)

    Default

    `newInt` has no length (`SetLength` is used to give arrays a length), so when you try to index it, it will error.
    replace:
    >> newInt[j] := ord(txt[i+j]);
    with the following, which will append the number to the back of your array:
    >> newInt := newInt + ord(txt[i+j]);

    the until-statement is not computed correctly, it's not a logical "and" in that situation, it's a bitwise and.
    replace the following to have it act as a logical and:
    >> until (j >= 4 and j>5 );
    with:
    >> until (j >= 4) and (j > 5);
    This is due to operator precedence (something you learned about in early math class - EG where multiplications are solved before addition). "And" servers two functions in pascal, if parenthesis isn't used `and` will be solved before comparison operations (<,>, <=, >=, =, <>). So without parenthesis the statement would be computed as `j >= (4 and j) > 5` - that's not what you want.

    Further more, "ord" is probably not what you are after, but StrToInt, to convert a string/character to the number it is (not just change it's type).



    I am not entirely sure what you are trying to achieve, but judging from the name of the function you wanna either extract floats from a string, or just check if it contains floats. Here is a function, it will extract and split up floats and numbers no matter how it looks in the text, it can be used for both purposes mentioned, for example to just check if the string contains a flaot you'd simply check if the result array is empty `if ExtractFloats('mystring') = [] then`.
    Simba Code:
    function ExtractFloats(str:String): array of Double;
    var
      i,depth:Int32;
      tmp:String;
    begin
      i := 1;
      while i <= Length(str) do
      begin
        while (i <= Length(str)) and (str[i] in ['0'..'9']) and (depth < 2) do
        begin
          tmp += str[i];
          if (i+2 <= Length(str)) and (str[i+1] = '.') and (str[i+2] in ['0'..'9']) then
          begin
            if depth = 0 then
            begin
              Inc(i);
              tmp += str[i];
            end;
            Inc(depth);
          end;
          Inc(i);
        end;

        if tmp <> '' then
        begin
          Result := Result + StrToFloat(tmp);
          tmp := '';
          depth := 0;
        end;
        Inc(i);
      end;
    end;

    var
      input:string;
    begin
      input := 'lo 21.3da 22. as1943 .123.43.123.99word';
      WriteLn('input:  ', input);
      WriteLn('output: ', ExtractFloats(input));
    end.
    Note that there can be bugs, I havn't tested this much, I wrote it up while writing this post, it's not pretty either.. It can be made more strict, unlike now where it "makes up" numbers

    I am sorry if I utilized concepts you are not familiar with, I tried to keep it relatively simple, just ask if you wonder about shit. If I don't answer someone else might.
    Last edited by slacky; 01-20-2017 at 11:12 PM.
    !No priv. messages please

  4. #4
    Join Date
    May 2008
    Location
    Canada
    Posts
    665
    Mentioned
    0 Post(s)
    Quoted
    7 Post(s)

    Default

    Man, I definitely need to brush up on my basic operators.
    Forgot all about length.
    And Thank you Slacky, your post made alot of sense. Yes, that was pretty much what I was trying to do, grabbing floats from strings
    Your codes makes sense . Just that it has been awhile since I last coded in general.
    Last edited by mrpickle; 01-20-2017 at 09:20 PM.

  5. #5
    Join Date
    May 2008
    Location
    Canada
    Posts
    665
    Mentioned
    0 Post(s)
    Quoted
    7 Post(s)

    Default

    Problems all solved ^^. Thank you!




    Simba Code:
    program new;

    //Finds and returns all floats in a string
    function ExtractFloats(str:String): array of Double;
    var
      i,depth:Int32;
      tmp:String;
    begin
      i := 1;
      while i <= Length(str) do
      begin
        while (i <= Length(str)) and (str[i] in ['0'..'9']) and (depth < 2) do
        begin
          tmp += str[i];
          if (i+2 <= Length(str)) and (str[i+1] = '.') and (str[i+2] in ['0'..'9']) then
          begin
            if depth = 0 then
            begin
              Inc(i);
              tmp += str[i];
            end;
            Inc(depth);
          end;
          Inc(i);
        end;

        if tmp <> '' then
        begin
          Result := Result + StrToFloat(tmp);
          tmp := '';
          depth := 0;
        end;
        Inc(i);
      end;
    end;

    //Finds and returns first float in a string.
    function FloatInStr(Str: String): Double;
    var
      strLength: integer;
      i, depth: integer;
      tmp: String;
      found: Boolean;

    begin
      strLength := Length(Str);
      found := false;
      while (i <= strLength) and (found = false) do
      begin
        while (i <= Length(str)) and (str[i] in ['0'..'9']) and (depth < 2) do
        begin
          tmp += str[i];
          if (i+2 <= Length(str)) and (str[i+1] = '.') and (str[i+2] in ['0'..'9']) then
          begin
            if depth = 0 then
            begin
              inc(i);
              tmp += str[i];
            end;
            Inc(depth);
          end;
          Inc(i);
          found := true;
        end;
        Inc(i);
      end;

      if tmp <> '' then
        Result := StrToFloat(tmp);

    end;

    var
      input, input2:string;
    begin
      input := 'lo.......aw97et17y122 21.3333a 22.4.2.4..66446.zzfqg...reio as13.43.123.99word';
      input2 := '@#$%^azc999.251 252s3.344...555.66881)';
      WriteLn('input:  ', input);
      WriteLn('output: ', ExtractFloats(input));
      writeln('output2: ', FloatInStr(input));
      WriteLn('output: ', ExtractFloats(input2));
      writeln('output2: ', FloatInStr(input2));
    end.

  6. #6
    Join Date
    Feb 2012
    Location
    Norway
    Posts
    995
    Mentioned
    145 Post(s)
    Quoted
    596 Post(s)

    Default

    Quote Originally Posted by mrpickle View Post
    Problems all solved ^^. Thank you!
    Simba Code:
    ...snip...
    For the purpose of just getting the first float from a string you can simplify the function quite heavily, here is one way to do it:
    Simba Code:
    function FloatInStr(Str: String): Double;
    var
      i:Int32;
      tmp:String;
    begin
      while (Inc(i) <= Length(Str)) and (not (str[i] in ['0'..'9'])) do {nothing};
      Dec(i);
      while (Inc(i) <= Length(str)) and (str[i] in ['0'..'9']) do tmp += str[i];
      if (i <= Length(str)) and (str[i] = '.') then tmp += '.';
      while (Inc(i) <= Length(str)) and (str[i] in ['0'..'9']) do tmp += str[i];
      Result := StrToFloatDef(tmp,0);
    end;
    I did a little code-golfing, heh..

    We can have it return NaN instead, just to ensure that you don't think there is a float in the string in the case it's not (atm it returns 0).

    Simba Code:
    const NaN:Single = Single(Int32(-1));

    function IsNan(n:Double): Boolean;
    begin
      try
        Result := (n=0) and (n=1);
      except
        Result := True;
      end;
    end;

    function FloatInStr(Str: String): Double;
    var
      i:Int32;
      tmp:String;
    begin
      while (Inc(i) <= Length(Str)) and (not (str[i] in ['0'..'9'])) do {nothing};
      Dec(i);
      while (Inc(i) <= Length(str)) and (str[i] in ['0'..'9']) do tmp += str[i];
      if (i <= Length(str)) and (str[i] = '.') then tmp += '.';
      while (Inc(i) <= Length(str)) and (str[i] in ['0'..'9']) do tmp += str[i];
      Result := StrToFloatDef(tmp,NaN);
    end;


    var
      n:Double;
    begin
      n := FloatInStr('hello12.4');
      WriteLn(IsNan(n), ', ', n); //A number!

      n := FloatInStr('hello');
      WriteLn(IsNan(n), ', ', n); //Not a Number (NaN) .. aka no number found in the str.
    end.
    I at least think this works in the current version of Simba..
    Last edited by slacky; 01-22-2017 at 07:41 AM.
    !No priv. messages please

  7. #7
    Join Date
    May 2008
    Location
    Canada
    Posts
    665
    Mentioned
    0 Post(s)
    Quoted
    7 Post(s)

    Default

    Wow, and I thought the thread would have ended. Cool Enthusiasm slacky

    This is so much cleaner and efficient. ty ty!

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •