Passing a string array into a function

Hi there,

I am having trouble running the following newTest.cxx in ROOT

[code]void printArray(string fArray[], int arraySize)
{
for(int i = 0; i < arraySize; i++){
cout << fArray[i] << “\n” << endl;
}
}

void newTest(){
string test1Array [] = {“one”, “two”, “three”};
int test1ArraySize = test1Array->size();
printArray (test1Array, test1ArraySize);
//cout << test1ArraySize << endl;
}[/code]

And I have no idea what I am doing wrong…root just crashes everytime

Thanks
Jason

It’s probably a bug in CINT’s handling of the precompiled STL “string” container.
See http://root.cern.ch/viewvc/trunk/cint/doc/limitati.txt and http://root.cern.ch/cint for some additional notes.
Try to compile your macro (using ACLiC, for example), it should work fine.
A fix for the CINT interpreter problem would be to change:
void printArray(string fArray[], int arraySize)
into:
void printArray(string *fArray, int arraySize)

Oh, really? So, built-in arrays in C++ have member-function size???
Do you understand, what

test1Array->size()

really does?
What would happen, if I have
string test1Arr[] = {“heheheheheh”, “die”};
and call

int test1ArraySize = test1Array->size();
printArray (test1Array, test1ArraySize);

Just to add a little more:

  1. tpochep is right. This isn’t valid code.
  2. Don’t use C arrays, use vector< string >
  3. Once you’re using a vector< string >, make sure you pass it around by reference or const reference.

Cheers,
Charles

p.s. When you have problems like this, it’s a good idea to try and compile the macro (.L macro.C+) which will find many errors.

Thanks for that, making that change to a pointer helped.

On a related note, I now would like to get the string array as the return value as well

[code]void convertName(string *testArray)
{
string finalArray [testArray->size()];
string chainName = “person”;

for(int i = 0; i < testArray->size(); i++){
	finalArray[i] = testArray[i] + chainName;
	}
	return (finalArray[]);

}

void newTest(){
string test1Array [] = {“one”, “two”, “three”};
string finalArray [] = convertName(test1Array);

for(int i = 0; i < finalArray->size(); i++){
	cout << finalArray[i] << endl;
	}

}[/code]

And ROOT says the return value of convertName is ignored everytime, and I have no idea why…

Cheers
Jason

VIVE L’AMOUR!
sorry, you are right that I didn’t notice the usage of “test1Array->size()” which returns just the length of the first element (so in the original example it “accidentally” returns the correct value 3, as the first element “one” is 3 characters long).
Just replace:
int test1ArraySize = test1Array->size();
with:
int test1ArraySize = (sizeof(test1Array) / sizeof(string));
The CINT interpreter problem with “string fArray[]” will still, of course, be solved by “string *fArray”.
The way you try to “convertName” will not work. Try:

void convertName(string *finalArray, string *testArray, int testArraySize)
{
  string chainName = "person";
  
  for(int i = 0; i < testArraySize; i++){
    finalArray[i] = testArray[i] + chainName;
  }
  
  return;
}

void newTest()
{
  string test1Array [] = {"one", "two", "three"};
  int test1ArraySize = (sizeof(test1Array) / sizeof(string));
  
  string finalArray [test1ArraySize];
  
  convertName(finalArray, test1Array, test1ArraySize);
  
  for(int i = 0; i < test1ArraySize; i++){
    cout << finalArray[i] << endl;
  }
  
  return;
}

A pitiful case, am I not?
Pepe Le Pew.

void convertName(string *testArray)
{
   string finalArray [testArray->size()];//1)final array has the number of elements, equal to the number
 //of symbols in the first string. 2) built-in array can have size which is a constant integral expression,
 //function call is not a integral constant expression.
   string chainName = "person";

   for(int i = 0; i < testArray->size(); i++){
      finalArray[i] = testArray[i] + chainName;
      }
      return (finalArray[]);//1)wrong syntax/2)in C++ you can not return array/3) function of type "returning void" can not return anything, can have only "return;" statement.

}

void newTest(){
   string test1Array [] = {"one", "two", "three"};
   string finalArray [] = convertName(test1Array);//there is no way to initialize array with such an expression.
   
   for(int i = 0; i < finalArray->size(); i++){//finalArrat->size() == string("one").size().
      cout << finalArray[i] << endl;
      }

}

Looking at this your code I can recommend you first read my answer to Pepe about array->size(), and read any book on C++, looks like you do not know basics, so do not experiment with CINT, just read about C++ first, since you do not know basic syntax.
Which programming language did you use before?

Hi tpochep,

First of all thanks for your tips and advices.

This is a forum for ROOT support, which I believe most users of ROOT have the main aim of doing analysis in physics (or other sciences) rather than perfecting the art of programming.

I am a physicist, not a computer scientist. I had gone through some C++ tutorials in my own time for my work so I believe I know most the basics, although not very well. If I had the time to read a book or go through a proper course on programming, I wouldn’t be posting on this forum. My aim is to analyse data rather than learning the best way to program something, so as long as I can get some advice on the code to do what I want it to, I am satisfied.

Cheers
Jason

[quote=“jasonyctam”]Hi tpochep,

First of all thanks for your tips and advices.

This is a forum for ROOT support, which I believe most users of ROOT have the main aim of doing analysis in physics (or other sciences) rather than perfecting the art of programming.

I am a physicist, not a computer scientist. I had gone through some C++ tutorials in my own time for my work so I believe I know most the basics, although not very well. If I had the time to read a book or go through a proper course on programming, I wouldn’t be posting on this forum. My aim is to analyse data rather than learning the best way to program something, so as long as I can get some advice on the code to do what I want it to, I am satisfied.

Cheers
Jason[/quote]

Ok, I agree, but in this case (you have no time to read a book on C++) - you’ll always have problems and difficulties with ROOT and CINT. Good or not, ROOT’s interpreter uses C/C++ as an input language. These languages are quite complex and dangerous, if you do not understand them - you’ve just demonstrated this. CINT has it’s own problems, bugs and limitations, multiply them by your absence of free time and you will not be able to work, as soon as you have more complex programs. Read at least something about arrays, passing arguments to functions and returning from functions, array to pointer conversions etc.
Where, in which tutorial did you find syntax “return arr[]”? And why did you decide, you can call ->size() on built-in array?

P.S.

There are no computer scientists in this forum, and what we are discussing has nothing to do with computer science.

I seemed to have found a solution that works in C++

[code]#include
#include
using namespace std;

int main ()
{
unsigned int i;

int myints[] = {16,2,77,29};
vector fifth (myints, myints + sizeof(myints) / sizeof(int) );

cout << “The contents of fifth are:”;
for (i=0; i < fifth.size(); i++)
cout << " " << fifth[i];

cout << endl;

return 0;
}[/code]

Which runs fine with g++. But when I modify it to

[code]#include
#include
using namespace std;

void newTest()
{
unsigned int i;

int myints[] = {16,2,77,29};
vector fifth (myints, myints + sizeof(myints) / sizeof(int) );

cout << “The contents of fifth are:”;
for (i=0; i < fifth.size(); i++)
cout << " " << fifth[i];

cout << endl;

}[/code]

to run it in ROOT, it tells me the following:

Error: Symbol fifth is not defined in current scope newTest.cxx:45: Error: Failed to evaluate fifth.size() Error: Binary operator oprand missing newTest.cxx:45:

Any ideas on the work around for this?

We’re now getting off-topic here, but…

There are several people who are computer scientists on this forum. I don’t think we should “limit” the conversation as soon as it starts to look “computer-sciency”… (e.g., it makes a lot of sense to suggest to people they should pass objects around by const reference instead of by value).

Cheers,
Charles

VIVE L’AMOUR!
again, I believe you’ve met a CINT limitation in your latest example (if you try the compiled version, e.g. “.x newTest.cxx++”, you should get no problems). For the moment I don’t know how to overcome it in any easy way.
Try to replace: vector<int> fifth (myints, myints + sizeof(myints) / sizeof(int) );with: vector<int> fifth; for (i = 0; i < (sizeof(myints) / sizeof(int)); i++) fifth.push_back(myints[i]);
BTW. I am a genuine [quote]computer scientists in this forum[/quote] if anybody had any (totally unjustified, of course) doubts :exclamation: :mrgreen:
I am stupid. No?
Pepe Le Pew.

Worked like a charm!! Thanks a lot!!