简体   繁体   中英

How do you check if string ends with another string in Ada?

There are canonical answers to this question for every popular language, even though that answer usually boils down to: "Use string.endsWith() from the standard library". For Ada, as far as I can find in the docs for the Fixed String package , there is no string.endswith function.

So, given two fixed strings A and B, how do you check if A ends with B?

declare
   A : constant String := "John Johnson";
   B : constant String := "son";
begin
   if A.Ends_With(B) then -- this doesn't compile
      Put_Line ("Yay!");
   end if;
end

My intent is to establish a standard answer for Ada.

A slight simplification of Simon's answer:

function Ends_With (Source, Pattern : String) return Boolean is
begin
   return Pattern'Length <= Source'Length 
     and then Source (Source'Last - Pattern'Length + 1 .. Source'Last) = Pattern;
end Ends_With;

Well, here's a possible solution:

main.adb

with Ada.Text_IO;       use Ada.Text_IO;
with Ada.Strings.Fixed; use Ada.Strings.Fixed;

procedure Main is

   A : constant String := "John Johnson";
   B : constant String := "son";

begin

   if Tail (A, B'Length) = B then
      Put_Line ("Yay!");
   end if;

end Main;

output

$ ./main
Yay!

UPDATE (2)

Another update (thanks @Brian Drummond for the comment; comment disappeared though), again using Tail . This is now almost identical to @Zerte's answer, except for the dependency on Ada.Strings.Fixed :

main.adb

with Ada.Text_IO;       use Ada.Text_IO;
with Ada.Strings.Fixed; use Ada.Strings.Fixed;
with Ada.Assertions;    use Ada.Assertions;

procedure Main is

   function Ends_With (Source, Pattern : String) return Boolean is
   begin
      return Source'Length >= Pattern'Length and then
        Tail (Source, Pattern'Length) = Pattern;
   end Ends_With;   

begin

   Assert (Ends_With ("John Johnson", "son")  = True);
   Assert (Ends_With ("hi", "longer than hi") = False);

   Assert (Ends_With (""  , ""  ) = True);
   Assert (Ends_With (" " , ""  ) = True);
   Assert (Ends_With (""  , " " ) = False);
   Assert (Ends_With (" " , " " ) = True);

   Assert (Ends_With ("n ", "n ") = True);
   Assert (Ends_With (" n", "n" ) = True);
   Assert (Ends_With ("n" , " n") = False);
   Assert (Ends_With (" n", " n") = True);

   Put_Line ("All OK.");

end Main;

output

$ ./main
All OK.

Here is an example without any explicit loops.

with Ada.Assertions; use Ada.Assertions;
with Ada.Text_IO; use Ada.Text_IO;

procedure Main is
   function Ends_With(Source : String; Pattern : String) return Boolean is
      result : Boolean := False;
   begin
      if Pattern'Length <= Source'Length then
         if Pattern'Length > 0 then
            result := Source((Source'Last - Pattern'Length + 1)..Source'Last) = Pattern;
         else 
            result := True;
         end if;
      end if;
      return result;
   end Ends_With;

begin

   Assert (Ends_With ("John Johnson", "son") = True);


   Assert (Ends_With (""  , ""  ) = True);
   Assert (Ends_With (" " , ""  ) = True);
   Assert (Ends_With (""  , " " ) = False);
   Assert (Ends_With (" " , " " ) = True);   

   Assert (Ends_With (""  , "n" ) = False);
   Assert (Ends_With ("n"  , "" ) = True);

   Assert (Ends_With ("n ", "n ") = True);
   Assert (Ends_With (" n", "n" ) = True);
   Assert (Ends_With ("n" , " n") = False);
   Assert (Ends_With (" n", " n") = True);

   Put_Line("All OK");
end Main;

As a slight simplification of Jim's answer , this works too:

   function Ends_With (Source, Pattern : String) return Boolean is
   begin
      if Pattern'Length > Source'Length then
         return False;
      else
         return Source (Source'Last - Pattern'Length + 1 .. Source'Last)
           = Pattern;
      end if;
   end Ends_With;

but, even better (thanks, Zerte),

function Ends_With (Source, Pattern : String) return Boolean is
  (Pattern'Length <= Source'Length and then
     Source (Source'Last - Pattern'Length + 1 .. Source'Last) = Pattern);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM