Lareaper
Lareaper

Reputation: 31

Ada- attempting to remove blank spaces from a string?

This question is in regards to a program I'm working on for an intro to programming class in Ada. The only packages I can use are the basic text, integer, and float packages. I'm writing a procedure right now to remove the spaces from the string and I keep getting a constraint error on the same line. This is the line:

if inputString(count) /= Character'Val(32) then

I have count set to start at 1 and then increment through a loop until the end of the string, which would in turn check each character of the string to see if it was different than the character value of a blank space (32). I was then going to include this line:

noSpace(count..count) := inputString(count..count) 

where noSpace is to be the string with no spaces. My line of thinking may be completely off and I may need to approach this from a completely different angle.

Update: I've now managed to get past the error message and successfully remove the spaces from my string. But now when I print the new string there is a random variety of characters and shaded spaces after it. I believe the problem is caused because the new string is shorter than the previous one and the last characters are different.

Upvotes: 1

Views: 4515

Answers (4)

ajb
ajb

Reputation: 31689

Just to show you another possible solution, although one I would never use in real life:

function Strip_Space (S : String) return String is
begin
    if S'Length = 0 then
        return "";
    elsif S (S'First) = ' ' then
        return Strip_Space (S (S'First + 1 .. S'Last));
    else
        return S (S'First) & Strip_Space (S (S'First + 1 .. S'Last));
    end if;
end Strip_Space;

And then there's the way I would really do it. I didn't read Simon's answer carefully enough to realize that he was sliding substrings around. The most efficient answer, I think, is similar to Mark's, but you don't actually need to count the spaces in the string first.

function Strip_Space (Input_String : String) return String is
    No_Space : String(1..Input_String'Length);

    Index : Positive := 1;
begin

    for I in Input_String'range loop
        if Input_String(I) /= ' ' then
            No_Space(Index) := Input_String(I);
            Index := Index + 1;
        end if;
    end loop;

    return No_Space(1 .. Index - 1);
end Strip_Space;

Upvotes: 1

Simon Wright
Simon Wright

Reputation: 25491

If there are spaces in your input string, the valid part of the output string must be shorter. I imagine you wrote something like

noSpace : String := inputString;

to start things off with noSpace as long as it would need to be if there were no spaces in inputString? then, as you squeeze the spaces out, you seem to be writing garbage (undefined characters) to the end of noSpace. This doesn’t matter so long as you only deal with the valid part.

I tried this:

with Ada.Text_IO; use Ada.Text_IO;
procedure Lareaper is
   function Strip_Space (S : String) return String is
      Result : String := S;
      Current : Positive := Result'First;
      Last : Natural := Result'Last;
   begin
      loop
         exit when Current > Last; --  processed the whole string
         if Result (Current) = ' ' then
            --  slide the rest of the string back one
            Result (Current .. Last - 1) := Result (Current + 1 .. Last);
            --  which reduces the length by 1 too
            Last := Last - 1;
         else
            --  non-space character, skip
            Current := Current + 1;
         end if;
      end loop;
      --  return only the part of the result that doesn't contain spaces
      return Result (Result'First .. Last);
   end Strip_Space;
begin
   Put_Line ('|' & Strip_Space ("") & '|');
   Put_Line ('|' & Strip_Space (" ") & '|');
   Put_Line ('|' & Strip_Space ("a") & '|');
   Put_Line ('|' & Strip_Space ("ab") & '|');
   Put_Line ('|' & Strip_Space (" a") & '|');
   Put_Line ('|' & Strip_Space ("a ") & '|');
   Put_Line ('|' & Strip_Space ("a b") & '|');
   Put_Line ('|' & Strip_Space (" a b ") & '|');
end Lareaper;

which outputs

$ ./lareaper 
||
||
|a|
|ab|
|a|
|a|
|ab|
|ab|

Upvotes: 2

Mark
Mark

Reputation: 6394

Probably the bug is hid somewhere else.

Try this:

with Ada.Text_IO;

procedure String_Remove_Space is

    function Count_Space( S : String ) return Natural is
        Sum_Of_Space : Natural := 0;
    begin
        for I in S'range loop
            if S(I) = ' ' then
                Sum_Of_Space := Sum_Of_Space + 1;
            end if;
        end loop;
        return Sum_Of_Space;
    end Count_Space;

    Input_String : String := "Apple is on the tree";
    Input_No : String := "AppleIsOnTheTree";

    No_Space : String(1..Input_String'Length - Count_Space(Input_String));

    Index : Positive := 1;
begin

    for I in Input_String'range loop
        if Input_String(I) /= ' ' then
            No_Space(Index) := Input_String(I);
            Index := Index + 1;
        end if;
    end loop;

    Ada.Text_IO.Put_Line(Input_String);
    Ada.Text_IO.Put_Line(No_Space);

end String_Remove_Space;

Upvotes: 4

manuBriot
manuBriot

Reputation: 2715

Count should start at InputString'First, not at 1. In particular, when InputString is created as a slice/substring of another string, it is very likely that its first character is not at index 1.

Upvotes: 1

Related Questions