Board index » delphi » functions program

functions program

hey, this is a functions program I wrote, it has 4 functions, copy, insert,
delete, and pos.  It is supposed to simulate these functions without
actually using them.  However,  for insert, delete and pos, I get an answer
but I have weird characters at the end...if anyone could help me debug it I
would really appreciate it.  Thanks
Jen

P.S.
written in turbo pascal 7.0

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
uses crt;

function mycopy(s:string; i, start:integer):string;
var
   string1,b:string;
   a:string;
   count:integer;
   begin
        clrscr;
        count:=0;
        write('Please enter a string ');
        readln(string1);
        write('What number place do you want to start at in the string? ');
        readln(start);
        write('How many letters do you want to take? ');
        readln(i);
        a:=string1[start];
        count:=1;
        repeat
        b:=string1[start+count];
        a:=a+b;
        inc(count);
        until count=i;
        write(a);
        readln;
   end;

function myinsert(s,letters:string):string;

var
   b:string;
   place,count:integer;
   begin
        clrscr;
        write('Please enter a string ');
                      readln(s);
        write('What would you like to insert? ');
                    readln(letters);
        write('Where do you want to insert it? ');
                     readln(place);
        count:=1;
        b:='';
        repeat
              b:=b+s[count];
              inc(count);
        until count=place+1;
        b:=b+letters;
        count:=1;
        repeat
              b:=b+s[count+place];
              inc(count);
        until count=length(s);
        write(b);
        readln;
   end;

function mydelete(s:string; start,num:integer):string;
var
   count:integer;
   b:string;

   begin
        clrscr;
        write('Please enter a string ');
        readln(s);
        write('Where do you want to start deleting? ');
        readln(start);
        write('How many letters do you want to delete? ');
        readln(num);
        count:=1;
        b:='';
        repeat
              b:=b+s[count];
              inc(count);
        until count=start;
        count:=0;
        repeat
              b:=b+s[count+start+num];
              inc(count);
        until count=length(s);
        write(b);
        readln;
   end;

function mypos(s,sub:string) :string;
var
   temp:string;
   count,final,scount,temps:integer;
begin
     clrscr;
     write('Please enter a string ');
     readln(s);
     write('Please enter a substring ');
     readln(sub);
     temp:='';
     scount:=1;
     count:=1;
     repeat
           if s[scount]=sub[count] then
              begin
                   temps:=scount;
                   repeat
                         temp:=temp+s[scount];
                         inc(scount);
                   until length(temp)=length(sub);
                   if temp=sub then
                      begin
                           final:=temps;
                           scount:=length(s)-1;
                      end;
                   inc(count);
              end;
           inc(scount);
     until scount=length(s);
     writeln('Your substring starts at position ',final);
     readln;
end;

var
   s,sub,letters:string;
   char1:char;
   i,start,place,num:integer;
begin
     clrscr;
     writeln('Please enter one of the following choices in lower case ');
     writeln('a) Copy function');
     writeln('b) Insert function');
     writeln('c) Delete function');
     writeln('d) Pos function');
     readln(char1);
     case char1 of
          'a': writeln(mycopy(s,i,start));
          'b': writeln(myinsert(s,letters));
          'c': writeln(mydelete(s,start,num));
          'd': writeln(mypos(s,sub));
     end;
end.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

 

Re:functions program


"Jen *smiles* =T" <smil...@home.com> wrote in message
news:4k6y6.138509$x27.7399501@news1.rdc2.on.home.com...

Quote
> hey, this is a functions program I wrote, it has 4 functions, copy,
insert,
> delete, and pos.  It is supposed to simulate these functions without
> actually using them.  However,  for insert, delete and pos, I get an
answer
> but I have weird characters at the end...if anyone could help me debug

it I

The way your program's written, you get a garbage string after every
output
anyway. This is a consequence of not clearly understanding the role of
functions; the problem you allude to is simply a matter of incorrect loop
limits.

Quote
> function mycopy(s:string; i, start:integer):string;
> var
>    string1,b:string;
>    a:string;
>    count:integer;
>    begin
>         clrscr;
>         count:=0;
>         write('Please enter a string ');
>         readln(string1);
>         write('What number place do you want to start at in the string?
');
>         readln(start);
>         write('How many letters do you want to take? ');
>         readln(i);
>         a:=string1[start];
>         count:=1;
>         repeat
>         b:=string1[start+count];
>         a:=a+b;
>         inc(count);
>         until count=i;
>         write(a);
>         readln;
>    end;

The problem is basically that you're not clear on what should be in the
function
and what should be in the main program or calling routine. To see why,
let's
take a look at what happens: you call the copy function with

  writeln(mycopy(s,i,start));

where, in fact, you haven't defined s yet in the main program (this itself
should be a warning!)

Now for this to work, mycopy has to use the value of s and return a string
related to s in some way. Your version does neither of these things: it
asks
the user for a string to use, processes it, stores the answer in the local
variable a, writes it and exits. So two things must change:

(1) Use s instead of asking the user for string1; getting the string is
the
job of the main program.
(2) When you have the final string, assign it to the function. Don't write
it; that's the job of the main program. In fact, don't do anything with
the
screen at all.

So your mycopy function should look like this:

function mycopy(s:string; i, start:integer):string;
var
   b:string;
   a:string;
   count:integer;
   begin
        a:=s[start];
        count:=1;
        repeat
            b:=s[start+count];
            a:=a+b;
            inc(count);
        until count=i;
        mycopy := a;
   end;

Note that there's really no need for b; you can simply use

   a := a + s[start + count];

Also, since you know how many characters you want, a FOR loop would be
better
than a REPEAT loop, so the function can be rewritten as follows:

function mycopy (s: string; i, start: integer): string;
var
    a: string;
    count: integer;
begin
    a := s[start];
    for count := 1 to i-1 do
        a := a + s[start + count];
    mycopy := a
end;

In fact you can do without a as well, using mycopy throughout; you can
assign to mycopy as often as you wish. That's up to you; it will trim
a string variable (and a line of code), so it's not a bad idea.

Similarly, myinsert can be written as follows (note that place should be a
parameter, not something asked for in the procedure):

function myinsert (s, letters: string; place: integer): string;
var
    b:string;
    count:integer;
begin
    count:=1;
    b := '';
    for count := 1 to place do
        b := b + s[count];
    b:=b+letters;
    for count := place + 1 to length(s) do
        b := b + s[count];
    myinsert := b;
end;

Note that your final loop was

Quote
>         count:=1;
>         repeat
>               b:=b+s[count+place];
>               inc(count);
>         until count=length(s);

This is incorrect. The final condition needs to be

        until (count + place) = length(s);

- we don't have length(s) characters left to copy, only
(length(s) - place). Similarly for mydelete.

Now mypos shouldn't return a string at all; it should return an integer.
Again, you need to eliminate user interaction from your procedure. But
there are worse problems with mypos - it really doesn't work at all!
If the first character of your substring appears *anywhere* before the
actual occurrence of the substring, your program will crash. Also, if
the substring doesn't appear, the result is undefined.

Note the following:

Quote
>            if s[scount]=sub[count] then
>               begin
>                    temps:=scount;
>                    repeat
>                          temp:=temp+s[scount];
>                          inc(scount);
>                    until length(temp)=length(sub);
>                    if temp=sub then
>                       begin
>                            final:=temps;
>                            scount:=length(s)-1;
>                       end;
>                    inc(count);
>               end;
>            inc(scount);

If we find a first-character match, we make temp a string containing
the next length(sub) characters of the string, and compare it to sub.
OK so far (except if we're too near the end of the string), but what
happens if temp <> sub? We increment count (which you shouldn't, but
that's a minor matter by comparison - by itself this would result in
some errors), and *next* time we find a character match we try the
following:
  repeat
    {add a character to temp}
  until length(temp) = length(sub);
But the second time we hit this loop, temp is already a string with
the same length as sub! So we make it longer, and longer, and longer...
and then we run out of space and the program crashes.

Rather than actually creating a new string (temp), we can instead
simply compare a fixed number of characters. I'll show you how it's
done each way. Note that Boolean variables are very useful for
keeping track of things like whether you have a match!
First, with a new string (i.e. a fixed version of your function):

function mypos (s, sub: string): integer;
var
    temp: string;
    found: Boolean;
    count, scount, temps:integer;
begin
    mypos := 0;  {default return value - indicates we couldn't find it}
    if (s = '') or (length(s) < length(sub)) then
        Exit;    {take care of unpleasant cases}
    found := false;

{Now note there's only so far we can go before we'll run out of
characters}
    for scount := 1 to length(s) - length(sub) + 1 do
        if not found then {if we've already found a match, skip the rest}
            if s[scount] = sub[1] then
                begin
                    temp := '';
                    for temps := 1 to length(sub) do  {get next
length(sub) characters}
                        temp := temp + s[scount + temps - 1];
                    found := (temp = sub);    {is it a match?}
                    if found then
                        mypos := scount;      {if so, set mypos}
                end;
end;

Rather than using a temporary string, we can just compare characters:

function mypos (s, sub: string): integer;
var
    found: Boolean;
    count, scount, temps:integer;
begin
    mypos := 0;  {default return value - indicates we couldn't find it}
    if (s = '') or (length(s) < length(sub)) then
        Exit;    {take care of unpleasant cases}
    found := false;

{Now note there's only so far we can go before we'll run out of
characters}
    for scount := 1 to length(s) - length(sub) + 1 do
        if not found then {if we've already found a match, skip the rest}
            if s[scount] = sub[1] then
                begin
                    found := true;  {OK so far}
                    for temps := 1 to length(sub) do  {next char okay?}
                        found := found and (s[scount + temps - 1] =
sub[temps]);
                    if found then   {we have a winner!}
                        mypos := scount;
                end;
end;

Now your main program should look like this:

program MyStrings;
uses
    Crt;
var
    s, sub, letters: string;
    char1: char;
    i, start, num: integer;
begin
    clrscr;
    writeln('Please enter one of the following choices in lower case ');
    writeln('a) Copy function');
    writeln('b) Insert function');
    writeln('c) Delete function');
    writeln('d) Pos function');
    readln(char1);
    write('Please enter the main string: ');
    readln(s);
    case char1 of
        'a':
            begin
                write('Please enter the start position: ');
                readln(start);
                write('Please enter the number of characters to copy: ');
                readln(i);
                writeln(mycopy(s, i, start));
            end;
        'b':
            begin
                write('Please enter the string to insert: ');
                readln(letters);
                write('Please enter the position at which to insert it:
');
                readln(start);
                writeln(myinsert(s, letters, start));
            end;
        'c':
            begin
                write('Please enter the position from which to start
deleting: ');
                readln(start);
                write('Please enter the number of characters to delete:
');
                readln(num);
                writeln(mydelete(s, start, num));
            end;
        'd':
            begin
                writeln('Please enter the substring to find: ');
                readln(sub);
                writeln(mypos(s, sub));
            end;
     end;
end.

Re:functions program


In article <4k6y6.138509$x27.7399...@news1.rdc2.on.home.com>,
Jen *smiles* =T <smil...@home.com> wrote:

Quote
>hey, this is a functions program I wrote, it has 4 functions, copy, insert,
>delete, and pos.  It is supposed to simulate these functions without
>actually using them.  However,  for insert, delete and pos, I get an answer
>but I have weird characters at the end...if anyone could help me debug it I
>would really appreciate it.  Thanks
>Jen

>P.S.
>written in turbo pascal 7.0

>~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>uses crt;

>function mycopy(s:string; i, start:integer):string;
>var
>   string1,b:string;
>   a:string;
>   count:integer;
>   begin
>        clrscr;
>        count:=0;
>        write('Please enter a string ');
>        readln(string1);
>        write('What number place do you want to start at in the string? ');
>        readln(start);
>        write('How many letters do you want to take? ');

I do not understand where is the beef, but do not mix IO and processing
like that.

You pass start as a parameter but then read it from the user?

Osmo

Other Threads