Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

result of a function

Posted on 1999-08-02
8
Medium Priority
?
136 Views
Last Modified: 2010-04-04
I have a function

func InsertParse(pstr, pdelim, pSubString : pChar) : pChar;


pstr is a string of integers separated by pdelim.  Each integer is coverted to a pChar before being passed, as is pSubString.  pDelim is a semicolon.  The result should come out as 1;2;3;4;5 ...

However, at odd times (not very predictably), one of the integers becomes a non-ascii char at the point when the debugger comes to the function's "end;" (when the local variables used for concatenation go out of scope)like:


s := String(pStr) + String(pDelim) + String(pSubString);
result := pChar(s);
l:=0;
end; (s goes out of scope here and function goes buggers)


On the line "l:=0;" the value of result is '1,2,3'
pressing f7 once more to get to the next line result goes to '1,2,#$10'.  

Does anyone know if this is a Delphi 4 bug.  If so, is there any way around it?  I have tried declaring "s" as a global variable :-( and it seems to work, but this function is used for other string building and the presence of the global variable wreaks havoc on those other instances.

the function in full:


//-- Insert the substring before the Position-th Delim-delimited piece
//-- of str.  If Position is missing (or 0) stick it at the end.
Function InsertParse(pStr, pDelim, pSubString : pChar; Position : Integer = 0) : pChar;
var
  s : string;
  n : Integer;
  p : pChar;

  //debug
  l : integer;

begin
  try
    If Position = 0 then
      begin
        if strlen(pStr) = 0 then
          begin
            S := string(pSubString)
          end //if strlen(pStr) = 0 then
        Else
          begin
            s := String(pStr) + String(pDelim) + String(pSubString);
          End; //else If Strlen(pStr) > 0 then
      end //If Position = 0 then
    Else
      begin
        For n := 1 To Position - 1 do
          s := string(InsertParse(pchar(s), pDelim,
               pChar(VarToStr(Parse(pStr, pDelim, n)))));
        s := string(InsertParse(pChar(s), pDelim, pSubString));
        For n := Position To Parse(pStr, pDelim) do
            s := string(InsertParse(pChar(s), pDelim,
                 pChar(VarToStr(Parse(pStr, pDelim, n))) ));
      End; //else if position <> 0 then
    InsertParse := pChar(s);
//    l := 1;
  except
    on e:exception do
    ShowMessage(e.message);
  end; //try except
End;//Function InsertParse
0
Comment
Question by:cestes001
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
  • 3
  • 2
8 Comments
 
LVL 10

Expert Comment

by:viktornet
ID: 1392525
Use the following function!

Function TForm1.GetParsedItem(TheItemStr, ParseStr : String; ItemNum : Integer): String;
 Var
  I4 : Integer;
  S4 : String;
Begin
TheItemStr := TheItemStr + ParseStr;
  S4 := '';
 I4 := 0;
 While I4 <= ItemNum Do
  Begin
   S4 := Copy(TheItemStr, 1, Pos(ParseStr, TheItemStr) - 1);
   Delete(TheItemStr, 1, Pos(ParseStr, TheItemStr));
   Inc(I4);
  End;
  Result := S4;
End;

..-=ViKtOr=-..
0
 

Author Comment

by:cestes001
ID: 1392526
Hi Viktornet:

I must have misstated the problem.  I have the function working and doing what I need it to do <inside the function>.  It is only when the result is assigned and the function's local variables go out of scope that the returned value gets mangled. To restate the crux of the problem:

s := String(pStr) + String(pDelim) + String(pSubString);
result := pChar(s);
l:=0;
end; (s goes out of scope here and function goes buggers)


On the line "l:=0;" the value of result is '1,2,3'
pressing f7 once more to get to the next line result goes to '1,2,#$10'.  

I'm hoping someone knows a way to keep the return value from getting mangled after the local vars go out of scope.

Regarding your response, I have a working parsing routine.  The routine in question is supposed to insert a string (char representation of an int, in this case) at the end of the pStr passed in.  Thanx for the effort.  
0
 
LVL 5

Expert Comment

by:heathprovost
ID: 1392527
I think you should do it Viktornet's way.  The reason you are having a problem is because your result type is a PChar (a pointer).  You are setting your result to a pointer to a local string variable.  As soon as your function exits the variable s is undefined and goes out of scope.  This only fails intermitantly because the memory space usually doesnt not get overriden immediately, and the string that was there is still readable.  But you cant do it this way.  It is better to use a string type, like viktornet's code does, and then typecast it on the other end.  That way the scope problem dissappears.  If you must use PChars, you should pass the Pchar (variable s) into the function as a var parameter, and fill it in your function.  then use the result for success/failure or do away with it altogether.  That way there is no scope problem either.  But I suggest doing it like Viktornet said using only String type variables.

Heath    
0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 5

Expert Comment

by:heathprovost
ID: 1392528
In my opinion, PChars should NEVER be used as result type for functions, unless you want to deal with the headaches associated with this or absolutely have to do it that way for compatibility with someone elses code.  They are in general too much trouble to deal with and there is usually a far easier way.

Heath
0
 

Author Comment

by:cestes001
ID: 1392529
To Viktornet and hethprovost:

I am coming to the same conclusions you state so eloquently, helped of course, by your advice.  However, since the results need to be passed back to a VB calling function, how do I get them in shape to pass them back.  Delphi strings won't do the job.

My thought was that the vb sub created the string and asked Delphi to fill it with value, like
  dim s as string
  s = someDelphifunc

What I thought would fill the s var was the value of result in someDelphiFunc.  This is apparently not so.  Now, I find a need to send the value of result back to the vb sub and pChar is apparently not the way.  

I am becoming convinced that a var parameter is the only way to get the value back in one piece.  

Now, how do I get the 50 points to Viktornet???
0
 
LVL 5

Expert Comment

by:heathprovost
ID: 1392530
I should have realized you were trying to do something with VB when I saw the function :).  Yes, doing this with a var parameter should solve your problem.  If you pass the address of your VB string variable to the delphi function you should be able to accomplish your task without having this scoping issue.  As for the points, viktornet will post an answer as soon as he sees your comment.

Heath  
0
 
LVL 10

Accepted Solution

by:
viktornet earned 200 total points
ID: 1392531
Thanks for letting me answer the question!

Heath, thanks for explaining why it didn't work while I was gone ;)

..-=ViKtOr=-..
0
 

Author Comment

by:cestes001
ID: 1392532
Viktornet:

No problem.  Sorry it took so long for me to grasp the concept.  I've been sweating this for several days.  Your explaination, along with a couple on newsnet got me thinking more clearly and the solution will require minimal coding.  There are a handful of functions with this problem and a number of calls to those funcs (on the vb side).  It could have been worse.  

Thanx again.
0

Featured Post

Important Lessons on Recovering from Petya

In their most recent webinar, Skyport Systems explores ways to isolate and protect critical databases to keep the core of your company safe from harm.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Objective: - This article will help user in how to convert their numeric value become words. How to use 1. You can copy this code in your Unit as function 2. than you can perform your function by type this code The Code   (CODE) The Im…
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…
This course is ideal for IT System Administrators working with VMware vSphere and its associated products in their company infrastructure. This course teaches you how to install and maintain this virtualization technology to store data, prevent vuln…
In this video you will find out how to export Office 365 mailboxes using the built in eDiscovery tool. Bear in mind that although this method might be useful in some cases, using PST files as Office 365 backup is troublesome in a long run (more on t…
Suggested Courses

670 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