String Manipulation


In Sage-ST TM , a string has two possible lengths: actual and apparent. The actual length is the length defined when a string is declared. The apparent length may be less than or equal to the actual length. Its end is signaled by an ASCII.nul character or the actual length, whichever comes first. SAGE always uses the apparent length of a string. Ada always uses the actual length of a string. This dual view of strings provides you with greater flexibility in your programming.

Throughout Sage-ST TM , strings are required as arguments to procedures. This is true for the Strings library or anywhere a file, relation, or field name is required. The Length procedure in the Strings package returns the apparent length. A field value from a database relation is often returned as a string or put into the relation using a string variable. All of these SAGE procedures that require strings use the apparent length of the string.

Sage-ST TM provides the following four packages to aid the user with string manipulation:

Strings - This package provides procedures used to manipulate logical strings using apparent lengths;

Convert - This package provides procedures used to convert an integer to a string, and a string into an integer;

ConvertReal - This package provides procedures used to convert from a string to a floating point number and from a floating point value to a string;

MoveLib - This is a low-level package that can be used to manipulate strings and other arrays. Because it uses addresses, care should be exercised so that nothing is inadvertently overwritten.

The following are examples of these packages and similar Ada commands. Some of the non-Sage-ST TM calls are from a package written by the United States Marine Corps at Albany, GA. As you can see, sometimes Ada is more convenient and appropriate, and sometimes Sage-ST TM is.
      with Convert;
      with ModSys;
      with MoveLib;
      with Strings; use Strings;
      procedure Samples is
      found : boolean;
      success : boolean;
      starting_Point : ModSys.S_natural;
      an_Integer : ModSys.S_natural;
      length_string_1: ModSys.S_natural;
      length_string_2: ModSys.S_natural;
      string_1 : string (1 .. 100);
      string_2 : string (1 .. 100);
      string_Value : string (1 .. 20);
      begin
      -- string_1 should contain the word "Sage-ST
      
        TM
      
      "
      Strings.Assign ("Sage-ST
      
        TM
      
      ", string_1, success); -- OR
      string_1 (string_1'first..string_1'first+6) := "Sage-ST
      
        TM
      
      ";
      -- fill in the remainder of string_1 with ascii.nuls
      Strings.NulFill (string_1, string_1); -- OR
      MoveLib.FillChar (string_1(string_1'first+7)'address, ascii.nul, string_1'length-6); -- OR
      string_1 (string_1'first+7..string_1'last) := (others => ascii.nul);
      -- set string_2 equal to string_1
      MoveLib.MoveLeft ( string_1(string_1'first)'address, string_2(string_2'first)'address, 7); -- OR
      string_2 := string_1;
      -- see if string_1 is equal to "CON"
      if Strings.Compare ("CON", string_1) = Strings.equal then null; end if;
      -- if the "use Strings" clause is not used, then the following format would
      -- be needed to accomplish the same thing as the above statement
      if Strings."=" (Strings.Compare ("CON", string_1), Strings.equal) then null; end if;
      if IS_EQUAL (string_1, "CON", false) then null; end if;
      -- where
      -- function IS_EQUAL ( LEFT , RIGHT : in STRING ;
      -- CASE_SENSITIVE : in BOOLEAN := TRUE )
      --  return BOOLEAN is
      -- LEFT_STRING : STRING ( 1 .. LEFT'length ) := LEFT;
      -- RIGHT_STRING : STRING ( 1 .. RIGHT'length ) := RIGHT;
      -- begin
      -- if LEFT_STRING'length /= RIGHT_STRING'length then
      -- return FALSE ;
      -- else
      -- for INDEX in 1 .. LEFT_STRING'length loop
      -- if not CHARACTER_UTILITIES.IS_EQUAL ( LEFT_STRING ( INDEX ),
      -- RIGHT_STRING ( INDEX),
      -- CASE_SENSITIVE) then
      -- return FALSE;
      -- end if;
      -- end loop;
      -- return TRUE;
      -- end if;
      -- end IS_EQUAL ;
      -- find the length of string_1
      length_string_1 := Strings.Length (string_1); -- equals 7, number of letters in "Sage-ST
      
        TM
      
      " -- OR
      length_string_1 := string_1'length; -- equals 100, defined of this string
      -- put the contents of string_1 in string_2, but right justify it and pad with blanks
      Strings.RightJustify (string_1, string_2); -- OR
      string_2 (string_2'last-6..string_2'last) := string_1 (string_1'first..string_1'first+6);
      string_2 (string_2'first..string_2'last-7) := (others => ' '); -- OR
      string_2 := RIGHT_JUSTIFY (string_1, string_1'length, ' ');
      -- where
      -- function RIGHT_JUSTIFY (THE_STRING : in STRING ;
      -- IN_WIDTH : in POSITIVE ;
      -- WITH_FILLER: in CHARACTER ) return STRING is
      -- WORK_STRING : STRING (1 .. THE_STRING'length) := THE_STRING;
      -- OUT_STRING : STRING (1 .. IN_WIDTH) := (others => ' ');
      -- FIRST : NATURAL := 0;
      -- LAST : NATURAL := 0;
      --
      -- begin
      -- if IS_NULL (THE_STRING) then
      -- OUT_STRING := (others => WITH_FILLER);
      -- else
      -- for INDEX in 1 .. WORK_STRING'length loop
      -- if not CHARACTER_UTILITIES.IS_NULL (WORK_STRING (INDEX)) then
      -- FIRST := INDEX;
      -- exit;
      -- end if;
      -- end loop ;
      -- for INDEX in reverse 1 .. WORK_STRING'length loop
      -- if not CHARACTER_UTILITIES.IS_NULL (WORK_STRING (INDEX)) then
      -- LAST := INDEX;
      -- exit;
      -- end if;
      -- end loop ;
      -- if ( LAST FIRST ) + 1 >= OUT_STRING'length then
      -- OUT_STRING := WORK_STRING ( LAST OUT_STRING'length + 1 .. LAST);
      -- else
      -- OUT_STRING (OUT_STRING'length (LAST FIRST) .. OUT_STRING'length) := WORK_STRING (FIRST .. LAST);
      -- OUT_STRING ( 1 .. OUT_STRING'length (LAST FIRST) 1 ) := ( others => WITH_FILLER );
      -- end if;
      -- end if;
      -- return OUT_STRING;
      -- end RIGHT_JUSTIFY ; THE_STRING
      -- find the length of string_2
      length_string_2 := Strings.Length (string_2); -- equals 100, padding plus # of letters in "Sage-ST
      
        TM
      
      " -- OR
      length_string_2 := string_2'length; -- equals 100, defined of this string
      -- see if the letters "SAGE" are found anywhere in string_1
      Strings.Position ("SAGE", string_1, starting_Point, found); -- OR
      for j in string_1'range loop
      starting_Point := string_1'first+j-1;
      found := ( string_1 (starting_Point..starting_Point+3) = "SAGE" );
      exit when found;
      end loop; -- OR
      starting_Point := NUMBER_OF ("SAGE", string_1, false);
      -- where
      -- function NUMBER_OF ( THE_STRING : in STRING ;
      --   IN_STRING : in STRING ;
      --   CASE_SENSITIVE : in BOOLEAN := TRUE )
      --   return NATURAL is
      -- WORK_IN_STRING : STRING ( 1 .. IN_STRING'length ) := IN_STRING ;
      -- WORK_THE_STRING : STRING ( 1 .. THE_STRING'length ) := THE_STRING ;
      -- COUNT : NATURAL := 0 ;
      -- begin
      -- if WORK_THE_STRING'length <= WORK_IN_STRING'length then
      -- for INDEX in WORK_IN_STRING'first ..
      -- WORK_IN_STRING'last WORK_THE_STRING'last + 1 loop
      -- if IS_EQUAL ( WORK_THE_STRING ,
      -- WORK_IN_STRING ( INDEX .. INDEX + WORK_THE_STRING'length 1),
      -- CASE_SENSITIVE ) then
      -- COUNT := COUNT + 1;
      -- end if;
      -- end loop;
      -- end if;
      -- return COUNT ;
      -- end NUMBER_OF ;THE_STRING IN_STRING
      -- convert some integer to a string
      Convert.IntToStr (an_Integer, string_Value, string_Value'length, success); -- OR
      string_Value := integer'image (an_Integer);
      end Samples
    
Go Back To Sage-ST TABLE OF CONTENTS

warren.merrill@inl.gov , ftp://sage.inel.gov
Copyright © 1989-2006. Battelle Energy Alliance