2016-06-20 3 views
0

Ich möchte in der Lage, eine Funktion mit einer Variablen oder einer Kombination von Variablen in der Befehlszeile aufrufen, wie:C++ argv [] als Beziehung zwischen Variablen mit CERN-ROOT

$ ./myFunction.exe "var1" 

oder

$ ./myFunction.exe "var1/var2" 

Später in meinem Skript definiere ich eine Variable float VAR, die entsprechend der Benutzereingabe definiert werden sollte. Für den ersten Fall, ich will:

float VAR = var1; 

... und für den zweiten Fall, ich will:

float VAR = var1/var2; 

Gibt es eine Möglichkeit in CERN ROOT Rahmen dieses benutzerdefinierten Zeichenfeld zu interpretieren als eine Beziehung zwischen Variablennamen wie dieser? Mir ist klar, dass dies eine Strecke ist, aber im Moment muss ich jedes Mal, wenn ich VAR ändern möchte, dies hart codieren, und ich würde es vorziehen, das nicht tun zu müssen.

Beachten Sie, dass diese Variablen in einem Ttree benannt sind, die ich von einer externen * .root Datei eingelesen, so dass ich dachte, es eine Möglichkeit sein kann VAR mit gROOT-> Process() zu definieren, aber ich haven Ich konnte es nicht herausfinden. Ich verstehe, dass dies in direktem C++ unmöglich ist, aber ich denke, das sollte mit ROOT möglich sein.

+1

Können Sie nicht einfach die Operation analysieren und es tun, als würden Sie mit einem Taschenrechner? – NathanOliver

+0

Was meinst du mit "parse die Operation"? Wenn es eine Zahl wie ein float oder ein int wäre, könnte ich std :: atof bzw. std :: atoi verwenden, aber das sind Namen von Variablen in meinem Skript, nicht Zahlen oder Strings oder irgendetwas. – awwsmm

+0

Nun, Sie würden eine Karte oder etwas ähnliches benötigen, das Sie eine Zeichenkette der Variablen zuordnen können, die die Zeichenkette darstellt, und dann können Sie die Werte ersetzen, sobald Sie die Zeichenkette analysieren. – NathanOliver

Antwort

1

Sind Sie auf ROOT 5 oder 6? Bei mir funktioniert dies auf ROOT 5,34:

In test.cpp

double x = 2; 
double y = 3; 
double z; 

void test(const char* arg) 
{ 
    gROOT->ProcessLine(TString("z=")+arg); 
    cout << z << endl; 
} 

In Root-Shell:

.x test.cpp("x/y") 

Ausgang:

0.666667 

Was nicht funktioniert ist mit x und y als lokale Variablen in test(), t seine Ergebnisse in

Error: Symbol x is not defined in current scope 
Error: Symbol y is not defined in current scope 

Die Variable z in diesem Beispiel wird auch in globalem Bereich geschaffen, so scheint es, die ProcessLine Funktion in globalem Bereich ausgeführt wird, nicht in dem Anwendungsbereich der Aufruffunktion.

+0

Das ist großartig, aber es ist etwa auf halbem Weg, was ich tun möchte. Ich möchte nicht in einer ROOT-Shell laufen müssen. Ich möchte in der Lage sein, die * .exe zu kompilieren und dann auszuführen. – awwsmm

+0

Mit leichter Modifikation (siehe Edit) läuft das auch im kompilierten Modus für mich, aufgerufen mit '.x test.cpp + (" x/y ")' –

0

Ich nehme an, Sie möchten nur arithmetische Ausdrücke in Ihre Routine übergeben. Wenn ja, hier ist eine alternative Lösung ROOT TFormula (in ROOT6) mit:

#include <iostream> 

#include "TFormula.h" 
#include "TString.h" 

int main(int argc, char **argv) 
{ 
    TFormula my_formula("my_formula", TString(argv[argc-1])); 

    my_formula.SetParNames("var1", "var2"); 
    my_formula.SetParameter("var1", 3.45678); 
    my_formula.SetParameter("var2", 8.76543); 

    // The formula does not define any variable so input to TFormula::Eval() is 
    // irrelevant 
    double dummy = 0; 

    std::cout << "my_formula: " << my_formula.GetExpFormula("clingp") << "\n" 
      << "result:  " << my_formula.Eval(dummy) << std::endl; 

    return EXIT_SUCCESS; 
} 

Der Nachteil ist, dass Sie Ihre Variablen in eckigen Klammern wickeln müssen [] wie folgt aus:

$ ./myFunction.exe "[var1]/[var2]" 
$ ./myFunction.exe "[var1]" 
$ ./myFunction.exe "[var1]/[var2]+[var1]*[var2]" 

Das ist die Notation für TFormulas Parameter.