Solved

problem with modifying the parameters of a function

Posted on 1998-12-31
14
160 Views
Last Modified: 2010-04-04

Hi experts,

the following function - Mashdi will surely recognize it - modifies
a string to a new user definded length.

function TrimKeyword(term: string; newlength: integer): string;
var
  i1, i2, size: integer;
  cut:string;
begin
  size := length(term);
  if size > newlength then begin
    cut := copy(term, 1, newlength);
    i1 := FindStr(cut, term, 1, maxInt);
    while i1 > 0 do begin
      i2 := FindStr(' ', term, i1 + newlength, maxInt);
      if i2 = 0 then begin
        Delete(term, i1 + newlength, maxInt);
        break;
      end;
      Delete(term, i1 + newlength, i2 - i1 - newlength);
      i1 := FindStr(cut, term, i1 + newlength, maxInt);
    end;
  end;
  TrimKeyword := term;
end;

The prototype of Findstr is as follows:

function FindStr(const subStr, str: string; fromPos, toPos: cardinal): cardinal; assembler

If I call this function, for example

Trimkeyword (abcdefgh,3);

it will cut all occurencies of "abcdefgh" or shorter in a masterstring to the substring "abc".

for example the scanning of source:

master:='abcdefgh bla bla bla abcd blka bla';

will result in

result:='abc bla bla bla abc bla bla'';

Now, in order to keep this very useful function as flexible as possible, it would be nice if
I could add the string to be scanned in the function,too.

I want to do something like:

result:=Trimkeyword(master,'abcdefgh',4');

now result will be:

result:='abc bla bla bla abc bla bla'';

I tried to it myself, but I have a problem here.
I don't find the the scanned string in the definition of Trimkeyword.

Can you please help me?

With kind regards

Mathes




0
Comment
Question by:mathes
  • 7
  • 6
14 Comments
 
LVL 10

Expert Comment

by:viktornet
ID: 1353989
I don't understand what you mean!! What's wrong with the TrimKeyword(master, 'abcdefgh', 4);???
0
 
LVL 20

Accepted Solution

by:
Madshi earned 20 total points
ID: 1353990
Hi Mathes, (hi Viktor,)

hmmm. Didn't look at your TrimKeyword try in detail. Use this one:

function TrimKeyword(master: string; match: string; minLen: integer) : string;
var minMatch : string;
    i1,i2,i3 : integer;
begin
  minMatch:=' '+copy(match,1,minLen);
  result:=' '+master+' ';
  try
    i1:=FindStr(minMatch,result,1,maxInt);
    i2:=length(result);
    while i1>0 do begin
      inc(i1);
      i3:=i1+minLen;
      while (i3<=i2) and (result[i3]<>' ') do inc(i3);
      if (i3-i1<=length(match)) and CompareMem(match[1],result[i1],i3-i1) then begin
        delete(result,i1+minLen,i3-i1-minLen);
        dec(i2,i3-i1-minLen);
        i3:=i1+minLen;
      end;
      i1:=FindStr(minMatch,result,i3,maxInt);
    end;
  finally result:=copy(result,2,length(result)-2) end;
end;

Regards, Madshi.
0
 

Author Comment

by:mathes
ID: 1353991
Dear Madshi,

thank you for your source code.

When I tried to compile your source, Delphi 3.0 showed me an error message:


in the line:


if (i3-i1<length(c1)) and CompareMem(c1[1],master[i1],i3-i1) then


Delphi complains about:


"incompatible types 'char' and 'pointer'.


Can you please tell me what is wrong here ?

With kind regards

Mathes

0
 
LVL 20

Expert Comment

by:Madshi
ID: 1353992
Hmmm. I'm using Delphi 4. I guess in Delphi 3 CompareMem was declared like this:
  CompareMem(p1,p2 : pointer; size: integer) : boolean;
In Delphi 4 it is declared like this:
  CompareMem(const p1,p2; size: integer) : boolean;
So please change the line to
  "if (i3-i1<length(c1)) and CompareMem(@c1[1],@master[i1],i3-i1) then "
and look if it runs now.

Regards, Madshi.
0
 

Author Comment

by:mathes
ID: 1353993
Dear Madshi,

thank you again for your help.

Well, now the source can be compiled by Delphi without errormessage, but this source code
does not change the string in the way I need it.

I tested it with:

procedure TForm1.Button1Click(Sender: TObject);
var
  teststring,resultstring: string;
begin
  teststring := 'keyword abcd keywo efg keywor hij';
  resultstring := TrimKeyword('keyword', teststring, 3);
end;


Now the resultstring actually should be:

resultstring:='key abcd key efg key hij';

But unfortunately it is:

resultstring:='keyword';

I don't understand why this happens. I changed the line in the way you asked me to edit it.
And I added the declaration of "c1", which was an unknown identifier in the original code.

Now the code is as follows:

function TrimKeyword(master: string; match: string; minLen: integer): string;
var
  minMatch, c1: string;
  i1, i2, i3: integer;
begin
  minMatch := ' ' + copy(match, 1, minLen);
  result := ' ' + master + ' ';
  try
    i1 := FindStr(minMatch, result, 1, maxInt);
    i2 := length(result);
    while i1 > 0 do begin
      inc(i1);
      i3 := i1 + minLen;
      while (i3 <= i2) and (result[i3] <> ' ') do inc(i3);
      if (i3 - i1 < length(c1)) and CompareMem(@c1[1], @master[i1], i3 - i1) then
      begin
        delete(result, i1 + minLen, i3 - i1 - minLen);
        dec(i2, i3 - i1 - minLen);
        i3 := i1 + minLen;
      end;
      i1 := FindStr(minMatch, result, i3, maxInt);
    end;
  finally result := copy(result, 2, length(result) - 2) end;
end;


What is wrong here?

With kind regards

Mathes
0
 
LVL 20

Expert Comment

by:Madshi
ID: 1353994
Hmmm. Sorry, please undo your changes. I think we both mixed up the both questions you asked about strings.
The code line you have written in your comment from "Friday, January 01 1999 - 04:39AM" in this question was from my code from the other question...   :-)))

So please use the original source from my answer. Then only add a "@" before the first two parameters. That's all.

But then please call
  resultstring := TrimKeyword(teststring, 'keyword', 3);
and NOT
  resultstring := TrimKeyword('keyword', teststring, 3);

Then it should work.

Regards, Madshi.
0
 

Author Comment

by:mathes
ID: 1353995
Dear Madshi,

yes it seems we both mixed it up. So I post the code again so we both have a look at the same lines:

function TrimKeyword(master: string; match: string; minLen: integer) : string;
   var minMatch : string;
       i1,i2,i3 : integer;
   begin
     minMatch:=' '+copy(@match,1,minLen);
     result:=' '+master+' ';
     try
       i1:=FindStr(minMatch,result,1,maxInt);
       i2:=length(result);
       while i1>0 do begin
         inc(i1);
         i3:=i1+minLen;
         while (i3<=i2) and (result[i3]<>' ') do inc(i3);
         if (i3-i1<=length(match)) and CompareMem(match[1],result[i1],i3-i1) then
   begin
           delete(result,i1+minLen,i3-i1-minLen);
           dec(i2,i3-i1-minLen);
           i3:=i1+minLen;
         end;
         i1:=FindStr(minMatch,result,i3,maxInt);
       end;
     finally result:=copy(result,2,length(result)-2) end;
   end;

If I add a @ to the first parameters as you adviced me, Delphi refuses to compile this function.

function TrimKeyword(@master: string; @match: string; minLen: integer) : string;
                     
                     ^
Delphi says: "identifier expected, but "@" found.

Can you please help me again? What is wrong here ?

With kind regards

Mathes

P.S.: Ja so was verruecktes. Und ich dachte bei "Madshi" mehr an was indisches oder pakistanisches.
Herzliche Gruesse aus Muenchen und ein gutes neues Jahr.

0
Highfive Gives IT Their Time Back

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

 
LVL 20

Expert Comment

by:Madshi
ID: 1353996
Hi Mathes,

I meant, you should add the "@" before the first two parameters of the CompareMem function, because (you remember?) the declaration of the CompareMem function differs from Delphi3 to Delphi4. It is the same problem as in the other question...

Ok, here the complete source:

function TrimKeyword(master: string; match: string; minLen: integer) : string;
   var minMatch : string;
       i1,i2,i3 : integer;
   begin
     minMatch:=' '+copy(@match,1,minLen);
     result:=' '+master+' ';
     try
       i1:=FindStr(minMatch,result,1,maxInt);
       i2:=length(result);
       while i1>0 do begin
         inc(i1);
         i3:=i1+minLen;
         while (i3<=i2) and (result[i3]<>' ') do inc(i3);
         if (i3-i1<=length(match)) and CompareMem(@match[1],@result[i1],i3-i1) then
   begin
           delete(result,i1+minLen,i3-i1-minLen);
           dec(i2,i3-i1-minLen);
           i3:=i1+minLen;
         end;
         i1:=FindStr(minMatch,result,i3,maxInt);
       end;
     finally result:=copy(result,2,length(result)-2) end;
   end;

Regards, Madshi.

P.S: Ein gutes neues Jahr nach München (hier gibt's auch Umlaute und das "ß")...
0
 

Author Comment

by:mathes
ID: 1353997
Hello Madshi,

your updated code can't work. because the "copy" function needs a string as parameter and not a pointer.


So in the line

minMatch:=' '+copy(@match,1,minLen);

Delphi finds an error: incompatible types string and pointer.

Do you know a workaround?

With kind regards

Mathes

P.S.: Schön, daß man hier auch Umlaute verwenden darf. Wie ist das Wetter bei Euch?
Hier haben wir ideales Computerwetter. Mal sehen, welche weiteren Fragen bei mir noch
auftauchen werden. Du wirst bestimmt bald zu den top 10 in der Hitliste gehören....
0
 

Author Comment

by:mathes
ID: 1353998
Hello Madshi,

your updated code can't work. because the "copy" function needs a string as parameter and not a pointer.


So in the line

minMatch:=' '+copy(@match,1,minLen);

Delphi finds an error: incompatible types string and pointer.

Do you know a workaround?

With kind regards

Mathes

P.S.: Schön, daß man hier auch Umlaute verwenden darf. Wie ist das Wetter bei Euch?
Hier haben wir ideales Computerwetter. Mal sehen, welche weiteren Fragen bei mir noch
auftauchen werden. Du wirst bestimmt bald zu den top 10 in der Hitliste gehören....
0
 
LVL 20

Expert Comment

by:Madshi
ID: 1353999
Hi Mathes,

oops, the '@' before the match is wrong, of course. I copied the sources from your comment and there it was...   :-)
Please just delete it.

Regards, Madshi.

P.S: Kalt ist es hier. Brrrrrr. Arbeite an den Top10...  :-)))
0
 

Author Comment

by:mathes
ID: 1354000
Dear Madshi,

I deleted the @ before the match,

but now Delphi says

CompareMem(match[1],@result[i1],i3-i1) then
                    ^
incompatible types: char and pointer.

I deleted the @ before result, but the error did not dissapear. What is wrong here?

function TrimKeyword(master: string; match: string; minLen: integer) : string;
        var minMatch : string;
            i1,i2,i3 : integer;
        begin
          minMatch:=' '+copy(match,1,minLen);
          result:=' '+master+' ';
          try
            i1:=FindStr(minMatch,result,1,maxInt);
            i2:=length(result);
            while i1>0 do begin
              inc(i1);
              i3:=i1+minLen;
              while (i3<=i2) and (result[i3]<>' ') do inc(i3);
              if (i3-i1<=length(match)) and
     CompareMem(match[1],@result[i1],i3-i1) then
        begin
                delete(result,i1+minLen,i3-i1-minLen);
                dec(i2,i3-i1-minLen);
                i3:=i1+minLen;
              end;
              i1:=FindStr(minMatch,result,i3,maxInt);
            end;
          finally result:=copy(result,2,length(result)-2) end;
        end;


With kind regards

Mathes

P.S.: Vielleicht schaffst Du sogar auch die Top 5....
0
 
LVL 20

Expert Comment

by:Madshi
ID: 1354001
Ahhhhh - we misunderstood us once again...  :-)))

I meant the "@" before the "copy(@match,...)", not the "@" before the "CompareMem(@match,...)"...

Ok, again the complete sources, I hope now it will work:

function TrimKeyword(master: string; match: string; minLen: integer) : string;
        var minMatch : string;
            i1,i2,i3 : integer;
        begin
          minMatch:=' '+copy(match,1,minLen);
          result:=' '+master+' ';
          try
            i1:=FindStr(minMatch,result,1,maxInt);
            i2:=length(result);
            while i1>0 do begin
              inc(i1);
              i3:=i1+minLen;
              while (i3<=i2) and (result[i3]<>' ') do inc(i3);
              if (i3-i1<=length(match)) and
     CompareMem(@match[1],@result[i1],i3-i1) then
        begin
                delete(result,i1+minLen,i3-i1-minLen);
                dec(i2,i3-i1-minLen);
                i3:=i1+minLen;
              end;
              i1:=FindStr(minMatch,result,i3,maxInt);
            end;
          finally result:=copy(result,2,length(result)-2) end;
        end;

Regards, Madshi.

P.S: Naja, vielleicht irgendwann mal...  :-)
0
 

Author Comment

by:mathes
ID: 1354002
Dear Madshi,

yes, now everything works. Thank you for your help.

With kind regards

Mathes

0

Featured Post

IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

The uses clause is one of those things that just tends to grow and grow. Most of the time this is in the main form, as it's from this form that all others are called. If you have a big application (including many forms), the uses clause in the in…
In this tutorial I will show you how to use the Windows Speech API in Delphi. I will only cover basic functions such as text to speech and controlling the speed of the speech. SAPI Installation First you need to install the SAPI type library, th…
Access reports are powerful and flexible. Learn how to create a query and then a grouped report using the wizard. Modify the report design after the wizard is done to make it look better. There will be another video to explain how to put the final p…
Polish reports in Access so they look terrific. Take yourself to another level. Equations, Back Color, Alternate Back Color. Write easy VBA Code. Tighten space to use less pages. Launch report from a menu, considering criteria only when it is filled…

746 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

17 Experts available now in Live!

Get 1:1 Help Now