root [0] TString command = "kill -9 "; // note the space in the end of the string
root [1] cout << command << endl;
kill -9
root [2] cout << (TString(command) += 12107) << endl; // we create a copy of the “command”
kill -9 12107
root [3] Int_t K = 12107;
root [4] cout << (TString(command) += K).Data() << endl; // we create a copy of the “command”
kill -9 12107
root [5] gSystem->Exec((TString(command) += K).Data()); //where “K” is process id.
sh: line 0: kill: (12107) - No such process
root [6] cout << command << endl; // note that we did not modify the original “command” string
kill -9
In fact you don’t even need to create the “command”. You can simply write:
root [0] Int_t K = 12107;
root [1] gSystem->Exec((TString("kill -9 ") += K).Data()); //where “K” is process id.
sh: line 0: kill: (12107) - No such process
I know “.Data()” is usually not needed (and it is not needed in my examples in this thread), but I have met cases where it was necessary (for no obvious reason). So, I always explicitly add it to what I write as examples. Sooner or later one will get a fairly cryptic error, and adding “.Data()” will be the solution.
It’s worth making sure you look to see if a given function can take a TString as an argument or needs a const char*. If you don’t need to pass a const char* and can use a more civilized type (e.g., std::string or TString), then that’s what one should use.
That’s more or less what I am trying to follow. In case the function/method expects a “const char *” parameter I always add “.Data()” (or “->Data()”) in my examples (and “TSystem::Exec” is such a method), even if I know that it’s not really needed (as “TSystem::Exec” will also happily eat a TString parameter). For unknown reasons, I have had cases in which the “automatic mechanism of type conversion” (from TString to “const char *”) did not work and I needed to manually add “.Data()” (or “->Data()”). As far as I remember this always happened in compiled code (i.e. the compiler issued errors).