Strange behavior of ROOT/CINT with function RemoveSubString(

Dear Rooters

I have written the following function to remove a substring:
TString RemoveSubString(const char *name, const char *substr)
{
TString outname = TString(name);
char *tmpname = new char[strlen(name) + 1];
char *delname = tmpname;
Int_t len = 0;
char *pos;

tmpname = strcpy(tmpname,name);
pos = strstr(tmpname,substr);
len = tmpname - pos;

if (len < 0) outname.Resize(TMath::Abs(len));
else outname = tmpname + strspn(tmpname,substr);

delete [] delname;

return outname;
}//RemoveSubString

When I test this function as macro.C I get the following
correct output:
root [0] .L macro.C
root [1] RemoveSubString(“My_Name_Delete”,“Delete”)
(class TString)"My_Name_"
root [2] RemoveSubString(“My_Name_Delete”,“DELETE”)
(class TString)"My_Name_Delete"
root [3]

Now I add the following debugging code to my function:
TString RemoveSubString(const char *name, const char *substr)
{
TString outname = TString(name);
char *tmpname = new char[strlen(name) + 1];
char *delname = tmpname;
Int_t len = 0;
char *pos;

tmpname = strcpy(tmpname,name);
pos = strstr(tmpname,substr);
len = tmpname - pos;

if (len < 0) outname.Resize(TMath::Abs(len));
else outname = tmpname + strspn(tmpname,substr);
cout << "tmpname= " << tmpname << endl;
cout << "pos= " << pos << endl;
cout << "len= " << len << endl;

delete [] delname;

return outname;
}//RemoveSubString

When I test this function as macro.C I get the following
strange and incorrect output:
root [3] .L macro.C
root [4] RemoveSubString(“My_Name_Delete”,“Delete”)
tmpname= My_Name_Delete
pos= Delete
len= -8
(class TString)"My_Name_"
root [5] RemoveSubString(“My_Name_Delete”,“DELETE”)
tmpname= My_Name_Delete
root [6] RemoveSubString(“My_Name_Delete”,“Delete”)
root [7] .q
pos=

Calling RemoveSubString() the first time gives still the
correct answer, but calling it again suppresses all output!

Does anybody know, why I get this strange behavior?
Is there a hidden error in function RemoveSubString()?

My system: root 4.00/03 from 26 March 2004 on MacOS X 10.3.1

Thank you in advance for your help.

Best regards and Happy Eastern
Christian

Hi Christian,

Sorry for not checking your code but if you want to replace
a substring in a TString why not use available functionality:

root [0] TString a(“aapmiesaapmies”)
root [1] a.ReplaceAll(“mies”,"")
(class TString)"aapaap"
root [2]

Best regards , Eddy

Dear Eddy

Thank you for this simplified version, which I will use.
(Somehow, I missed this solution.)

Nevertheless, I am curious what the reason for this strange
behavior of my solution could be.

Best regards
Christian

Hello Christian,

In your code, you do

pos = strstr(tmpname,substr);

and then,

cout << "pos= " << pos << endl;

If substr is not found in tmpname, pos is 0.
Giving (char*) to cout causes strange behavior.

Thank you
Masa Goto

Dear Masaharu

Thank you for giving an explanation to one of the problems.
However, the line before:
cout << "tmpname= " << tmpname << endl;
is also not printed, and without the “cout” lines everything works fine.

Maybe, I do not know enough about the inner workings of CINT.

Best regards
Christian

Hello Christian,

As far as I tried on my Cygwin, adding if(pos) just before cout << pos
solves the problem. Will you try it?

if(pos) cout << “pos=” << pos << endl;

I don’t know why output from previous line does not show up. It does, at least, on my Cygwin.

Thank you
Masa Goto

Dear Masaharu

Thank you for this solution, now everything works fine, even the
output from the previous line shows up.

Best regards
Christian