Reputation: 67
I need to delete short words (shorter that three symbols) in a string ended by a dot. And after to display that string without these words.
So we need a string from a user as an input like this: "This is a simple string a man types." And in this string the program should delete each word that is shorter than three symbols. In our string these are: "is, a, a". So the output should be "This simple string man types."
It's Pascal/Delphi task for my programming course.
I've been thinking about this simple problem for a couple of days and apparently ran out of ideas how to solve it and ask for your help. I tried different loops for the main part which is to basically find sequence of less then three symbols between spaces. I am trying to debug it for quite some time, but to no results.
I use Lazarus 1.6.2, FPC 3.0, and Mac OS X v10.11 (El Capitan). My code is the following:
VAR
UserString: string;
i, n: byte; // Counters for the symbols in the string. 'i' counts every symbol.
again: boolean; // In case we need to repeat the program again
UserAnswerRepeat: char;
label repeat_again;
BEGIN
again:=false;
repeat_again: // Label to repeat the program
Writeln('Enter your string (ended by a dot):');
Readln(UserString);
// MAIN LOOP:
n:=1; // 'n' counts symbols in the words
for i:=1 to length(UserString) do
begin
while (UserString[i] <> ' ') do inc(n); // Here I have Range Check Error. Don't know how to get rid of it.
if (UserString[n] <> ' ') and (n<3) then
begin
delete(UserString, i-n, n);
n:=1
end;
end;
Writeln('The result is: ', UserString);
Writeln('Do you want to repeat the program? (Y/N)');
Readln(UserAnswerRepeat);
if (UserAnswerRepeat = 'Y') or (UserAnswerRepeat = 'y') then
again:=true;
if (again = true) then
goto repeat_again;
END.
Another minor question is: How do you make your console application repeat after the successful run? Here I used labels and goto. Maybe there's another nice way to do it again?
Upvotes: 1
Views: 1191
Reputation: 2591
In this situation look for the word separator. In your case it is 'space'. Also, count for the last word before the dot as it is not followed with 'space'.
One way to write your main loop is:
var
LastPos, I: Integer;
Tmp, UserString: String;
begin
LastPos := 1;
Tmp := '';
for I := 1 to Length(UserString) do
begin
if (UserString[I] = ' ') or (I = Length(UserString)) then
begin
if (I - LastPos >= 3) then Tmp := Tmp + Copy(UserString, LastPos, I - LastPos + 1);
LastPos := I + 1;
end;
end;
UserString: = Tmp;
end;
Upvotes: 2
Reputation: 26376
A different approach:
uses classes;
var v : TStringlist;
i : integer;
begin
v :=TStringlist.create;
v.strictdelimiter:=true;
v.delimiter:=' ';
v.delimitedtext:='This is a simple string a man types';
for i:=v.count-1 downto 0 do
if length(v[i])<3 then
v.delete(i);
writeln(v.delimitedtext);
v.free;
end.
Upvotes: 1
Reputation: 67
Thank you all again for pointing to the right direction. I finally managed to came up with the solution I initially intended, so that the program actually deletes the short (less then 3 symbols) words. Here's what I got:
VAR
UserString: string; //должна быть строка на 40 символов и точку в конце
i, n: byte;
BEGIN
Writeln('Enter the string:');
Readln(UserString);
i:=0;
n:=1;
repeat //MAIN LOOP:
inc(i);
if (UserString[i] = ' ') or (UserString[i] = '.') then
begin
if (i-n<3)then
begin
delete(UserString, n, i-n+1);
i:=n-1;
end;
n:=i+1
end
until (UserString[i] = '.') or (i>length(UserString));
Writeln('Result String: ', UserString);
END.
Any suggestions welcomed! Also there's an open question about making the program repeat in console mode. Is labels the best way to do it (see first code in question part)?
Upvotes: 1
Reputation: 21045
A for
loop start and end values for the control variable are evaluated only once. You set the end value to the length of the string. However, during the loop you remove parts from the string, and therefore the end value is past the end of the string. Try with a while
loop or repeat .. until
loop.
The actual reason for the error is in the line
while (UserString[i] <> ' ') do inc(n);
How long will the loop continue? What ends the loop?
You also need to rethink how you calculate characters using n
.
Upvotes: 1