Using argv and argc in Root

Hello all,
I would like to pass some parameters to root like the filename and output filename. I cannot seem to get the argc and argv working however. Stripped of the main code, here is what I have:

[code]#include <stdlib.h>
#include <stdio.h>

int main(int argc, char** argv)
{
return 0;
}[/code]

When executed (.x text.C), I get the following error:
root [9] .x test.C
Error: Function test() is not defined in current scope :0:
*** Interpreter error recovered ***

How do I solve this? thank in advance.

Hi,

why don’t you rename that function to test(const char* something, int count, double val){...} (the parameters are just examples), save it in test.C, and then call root "text.C\(\"some test\",42,3.141\)" that way your function will be called with these three parameters.

Cheers, Axel.

[quote=“Axel”]Hi,

why don’t you rename that function to test(const char* something, int count, double val){...} (the parameters are just examples), save it in test.C, and then call root "text.C\("some test",42,3.141\)" that way your function will be called with these three parameters.

Cheers, Axel.[/quote]I think, there is a typo above. The name of the function should match the name of the file.

Thanks Axel and Fine,
I rewrote the code as you suggested with the changes being:

root-to-singles(const char* inputfile, const char* outputfile){ ... TFile f(inputfile); ... ... out=fopen(outputfile,"w"); }

At the command prompt, I cannot get the " matching
> root "root-to-singles.C(“18root.root”,“somerot.txt”)"
Unmatched ".

So I opened root and tried the following:
root [0] “root-to-singles.C(“18root.root”,“somerot.txt”)”
(const char* 0x8a71264)"root-to-singles.C(“18root.root”,“somerot.txt”)"
root [1] .x "root-to-singles.C(“18root.root”,“somerot.txt”)"
Error in TRint::ProcessFile: macro "root-to-singles.C\ not found in path .:/home/.GATE/ROOT-5.14/share/root/macros:
root [2] .x root-to-singles.C(“18root.root”,“somerot.txt”)
Error in TRint::ProcessFile: macro root-to-singles.C\ not found in path .:/home/.GATE/ROOT-5.14/share/root/macros:

Thanks for the previous answers. As you can judge from the nature of the questions, I am rather new to Root and this forum has been of great use.

[quote=“pru”]At the command prompt, I cannot get the " matching
> root "root-to-singles.C(“18root.root”,“somerot.txt”)"
Unmatched ".

.[/quote]There are 2 problems with your example:

  1. The name of the file should match the name of the function inside of your file.
    Even though the file name can contain the “dash” symbol “-” the name of the C++ function can not. The later is the C++ syntax rule :exclamation: rather one of ROOT.
  2. Use the single quotation :bulb: instead of the “double” one

root 'root_to_singles.C("18root.root","somerot.txt")'From the ROOT prompt do

Just in case someone else is reading this in the future:

On my system

root ‘root2singles.C("18root.root","somerot.txt")’

and

root “root2singles.C("18root.root","somerot.txt")”

do not work ie the quotes

> root root2singles.C("18root.root","somerot.txt")

works.

Thanks to Fine and Axel.

[quote=“pru”]Just in case someone else is reading this in the future:

On my system

root ‘root2singles.C(“18root.root”,“somerot.txt”)’

and

root “root2singles.C(“18root.root”,“somerot.txt”)”

do not work[/quote]Try

 root 'root2singles.C("18root.root","somerot.txt")'

Generally, there is a problem: how to run the ‘root’ from shell command line,
and pass args to the application invoked via ‘root’ - usually it is more
convenient then typing-in these args as answers to questions if the shell
allows recalling few previous commands and making corrections in them.

At least some versions of ‘root’ (I guess sufficiently new ones)
have functions Argc(), Argv() in TApplication class. Example:

{ int argc, ai; argc=gApplication->Argc(); for(ai=0; ai<argc; ai++) printf("a[%d]=%s\n", ai, gApplication->Argv(ai)); }
Or use const char **argv=gApplication->Argv(); to have argv like in usual C.
But, to make things harder, the output of the example code is like:

$ root -l -n -b -q args_n1.C This is a nice cat. Warning in <TApplication::GetOptions>: macro This not found Warning in <TApplication::GetOptions>: macro is not found Warning in <TApplication::GetOptions>: macro a not found Warning in <TApplication::GetOptions>: macro nice not found Warning in <TApplication::GetOptions>: macro cat. not found root [0] Processing args_n1.C... a[0]=/home/mkk/root/bin/root.exe a[1]=-splash a[2]=-l a[3]=-n a[4]=-b a[5]=-q a[6]=args_n1.C a[7]=This a[8]=is a[9]=a a[10]=nice a[11]=cat.
So one needs to guess where is ‘argv[0]’ - the ‘args_n1.C’ in this case.
Also, these args specified are attempted to recognize as macro names.

In older versions of ‘root’ one may get these args from /proc/self/cmdline
(in Linux only), using the following code produces the same result:

{ char argbuf[2048], *argv[64]; FILE *cfd=fopen("/proc/self/cmdline","r"); int ai, ao, argc, abl=fread(argbuf,1,sizeof(argbuf),cfd); fclose(cfd); for(ao=argc=0; ao<abl && argc<64; argc++, ao++) ao+=strlen(argv[argc]=argbuf+ao); if(argc<64) argv[argc]=0; for(ai=0; ai<argc; ai++) printf("a[%d]=%s\n", ai, argv[ai]); }

Names of files processed by ‘root’, like the ‘args_n1.C’ in the example,
can be obtained using the following code:

{ Int_t i,f,l; TObjArray *ifl; TObject *obj; ifl=gApplication->InputFiles(); f=ifl->LowerBound(); l=ifl->GetLast(); printf("low:%d, last:%d; %d entries\n", f, l, ifl->GetEntries()); for(i=f; i<=l; i++) { obj=ifl->At(i); printf("if[%d]=%s\n", i, obj->GetName()); } }

However, I found passing arguments via environment variables to be
more convenient, as it does not interfere with TApplication::GetOptions

gSystem->Getenv(name);

gets a variable value as a string. If the shell is ‘bash’, these arguments
can be specified in the command line used to invoke root, like: a=1 b=2 f=datafile.txt root my_root_app.C to pass ‘a’, ‘b’ and ‘f’ arguments to the application (the bash is commonly used on Linux,
and some antiquted version is available for Windows, to be used in terminal window).
img_view.C (4.79 KB)