Reputation: 31
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
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
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
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
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