TObjString array

Hi
I was looking at the explanation of TObjString at the following link:

root.cern.ch/phpBB2/viewtopic.ph … ing+string

and honestly I do not have clear how that structure works. Even I get more confused when working with the pointer (*) and reference (&) for this type of objects. What is a TString& ? Will return a string? or a *char?

I have the following issue:

(…)

TObjString* filename[20];
char *dirName = new char[100];

(…)

strcpy(dirName,"/export/home/workspace/analysis/dataAm/am-carbon_200807/");
filename[NF1]->SetString(strcat(dirName,“co-cs3600sec.spe”))

But I get the following error precisely because of that last line:

root [0] .x peakfit.C
Error: Unexpected EOF G__fignorestream():3 LaBr3_data.h:262:
Advice: You may need to use +P or -p option
root[1]

I appreciate any comments of what I am doing wrong.
I also want to ask your advice about the strcat() function.
What I want to do is this: strcat(dirName,fileName)
However the strcat() modifies the pointer of my dirName in such way that it does the concatenation of strings, changing dirName into dirName + fileName .Is there any function that returns the concatenation of strings without affecting the initial pointer to dirName?
Just because I want to use the variable -dirName- to load other files in the same directory. Something like:

filename[NF1]->SetString(strcat(dirName, file1);
filename[NF2]->SetString(strcat(dirName, file2);
(etc…)

Thank you,

Hi Cristian,

Seems to be a mix of C and C++ . Why not use all the TString
functionality:

TObjString* filename[20];
const TString dirName ="/export/home/workspace/analysis/dataAm/am-carbon_200807/";

filename[NF1] = drirName+“co-cs3600sec.spe”;

Eddy

[quote=“Eddy Offermann”]Hi Cristian,

Seems to be a mix of C and C++ . Why not use all the TString
functionality:

TObjString* filename[20];
const TString dirName ="/export/home/workspace/analysis/dataAm/am-carbon_200807/";

filename[NF1] = drirName+“co-cs3600sec.spe”;

Eddy[/quote]

Hi Eddy
Yes, that seems to solve my problem. I have the feeling there are many ways around this problem, when working with array of Strings an this is one of them.

Something that I notice is that you made the following call:
TObjString* filename[20];

but I did the follwoing call:
TObjString filename[20];

Which honestly it is not clear to me the difference. Should not be TObjString already and array of pointers? Why does TObjString exist if we have already TString class? I would really appreciate if somebody give me some light about this topic which I do not have clear.

Another question… now that I have an array of pointers of TObjStrings instead of an array of objects, the following statement became illegal:

filename[k]->GetName();
or this other statment which returns the same thing (the string stored in the “k” position):
filename[k]->GetString()->Data();

I get the following error:

root [0]
Processing peakfit.C…
Error: illegal pointer to class object filename[k] 0x0 306 peakfit.C:45:
*** Interpreter error recovered ***
root [1]

Please help :stuck_out_tongue:
Thank you,

Kris

P.S. I promise I will stop missing C/C++ :slight_smile: Is that EZ?

The following work for me:

TObjString filename[NFILES];
const TString dirName = “/export/home/workspace/analysis/dataAm/am-carbon_200807/”;
filename[NF1] = (char *)(dirName.Data() + “co-cs3600sec.spe”);

(…)

printf(“Filename to process: %s\n”,filename[k]->GetName());
if ((fp = fopen(filename[k]->GetName(),“r”)) == NULL)
{
printf(“File not found!\n”);
}

:slight_smile: Thank you guys! Still any other comments are appreciated. I still have a problem and it is that it does not print correctly the first value stored in the first position of the array:
printf(“Filename to process: %s\n”,filename[0]->GetName());
returns ""
when it should return a non-empty string since I did assigned a value before:
filename[0] = (char *)(dirName.Data() + “co-cs3600sec.spe”)

Hi,

if you want to write C++ you should read an introduction / tutorial on it; there are plenty on the web. You’ll e.g. need to learn what references and pointers are. Knowing the basic concepts of a programming language is not really optional when writing code with it. You’re welcome to ask for help, but it’s easier for us to help you when you understand the basics.

Cheers, Axel.

Axel
I think it is straigh to understand the pointer and reference variables. I will light to have clarify what are the differences of the TObjString and the TString classes. In particular… dealing with TObjStrings… I found on the web it is not wise to have an anrray of pointers of TObjStrings
root.cern.ch/root/roottalk/roottalk00/2254.html

AND quating from the last link:
"
Anyway, since this doesn’t seem to work in CINT, I’m not sure my
comments will be too helpful, but maybe… The best way to do what you
really want in CINT is probably something like this, but it’s not at
all elegant:

const Char_t *vars[23] = { “Blah”, “Blah”, “Blah” … };
TObjString Avars[23];
for (int i = 0; i<23; i++) {
Avars[i] = vars[i];
}

"

Which as it looks to me, to have declared to sets of variables, to store the same data. I am sure there are advantages of having TObjStrings and access to all its functions and inherited functions from the TString class…

I would like to finsih this posting by asking the question… what is the best structure dealing with array of strings in ROOT… What about creating a TObjArray to do this task?

Cristian

[quote=“Eddy Offermann”]Hi Cristian,

Seems to be a mix of C and C++ . Why not use all the TString
functionality:

TObjString* filename[20];
const TString dirName ="/export/home/workspace/analysis/dataAm/am-carbon_200807/";

filename[NF1] = drirName+“co-cs3600sec.spe”;

Eddy[/quote]

Eddy afte further testing it seems what you suggested did not work. Could you check please those statements?

cristian@NARUTO:~$ root


  •                                     *
    
  •    W E L C O M E  to  R O O T       *
    
  •                                     *
    
  • Version 5.15/06 24 April 2007 *
  •                                     *
    
  • You are welcome to visit our Web site *
  •      [root.cern.ch](http://root.cern.ch)            *
    
  •                                     *
    

Compiled on 13 May 2007 for linuxx8664gcc with thread support.

CINT/ROOT C/C++ Interpreter version 5.16.19, March 16, 2007
Type ? for help. Commands must be C++ statements.
Enclose multiple statements between { }.
root [0] TObjString* filename[20];
root [1] const TString dirName ="/export/home/workspace/analysis/dataAm/am-ca$
root [2] filename[NF1] = dirName+“co-cs3600sec.spe”;
Error: Symbol NF1 is not defined in current scope (tmpfile):1:
Error: Incorrect assignment to filename[NF1], wrong type ‘TString’ (tmpfile):1:
*** Interpreter error recovered ***
root [3] .q

This might work as string array for ROOT. I guess an array of objects will do fine too.

root [6] char result = new char[10];
root [7] result[3]= new char[20];
root [8] strcpy(result[3],“wht”);
root [9] result[3]
(char
0x92d6c78)“wht”

Hi,
use a std::vectorstd::string if you don’t need the TObject inheritance.
Cheers, Axel.

Hi,

The purpose of TObjString is to allow the storing of a TString (which does not inherit from TObject) in one of the ROOT ‘polymorphic’ collections (TList, TObjArray, TClonesArray). If you do not need to use this polymorphic collections, you do not need to use TObjString.

Cheers,
Philippe

Hi Phillipep

Thanks for pointing that out. I was trying to make an array of TObjStrings by envoquing TobjString *myStrings[]; Instead I should do it this way:

TObjArray myStrings = new TobjArray(10);
myStrings.Add(s);
for(Int_t i=0;i<10;i++){
stg = (TObjString
) (myStrings.at(i));
printf("%s\n",str->GetName());
}
Cristian