How to pass command line arguments in Mac Application

2

I have created a Command line tool application ( Xocde --> New App --> Command line tool) and it's running without any problems. Now i want to run it through terminal and pass some command line arguments, something like this:

int main(int argc, const char * argv[])
{
    std::cout << "got "<<argc<<" arguments";
    for ( int i = 0; i<argc;i++){
        std::cout << "argument:"<<i<<"= "<<argv[i];
    }
    //// some other piece of code 
}

If I type in the terminal:

open VisiMacXsltConverter --args fdafsdfasf

I am getting the following output:

got 1 argumentsargument:0= /Applications/VisiMacXsltConverte

I want to know what is the correct way to pass arguments through command line.

When i tried

open  AppName --rwqrw
open: unrecognized option `--rwqrw'
Usage: open [-e] [-t] [-f] [-W] [-R] [-n] [-g] [-h] [-b <bundle identifier>] [-a <application>] [filenames] [--args arguments]
Help: Open opens files from a shell.
      By default, opens each file using the default application for that file.  
      If the file is in the form of a URL, the file will be opened as a URL.
Options: 
      -a                Opens with the specified application.
      -b                Opens with the specified application bundle identifier.
      -e                Opens with TextEdit.
      -t                Opens with default text editor.
      -f                Reads input from standard input and opens with TextEdit.
      -F  --fresh       Launches the app fresh, that is, without restoring windows. Saved persistent state is lost, excluding Untitled documents.
      -R, --reveal      Selects in the Finder instead of opening.
      -W, --wait-apps   Blocks until the used applications are closed (even if they were already running).
          --args        All remaining arguments are passed in argv to the application's main() function instead of opened.
      -n, --new         Open a new instance of the application even if one is already running.
      -j, --hide        Launches the app hidden.
      -g, --background  Does not bring the application to the foreground.
      -h, --header      Searches header file locations for headers matching the given filenames, and opens them.

Rohan

Posted 2012-05-17T08:35:35.373

Reputation: 121

I don't think you need the "--" part. Just start your app with: "./application argument" – Apache – 2012-05-17T08:43:02.727

Answers

2

Don't use open to launch command-line applications. It's supposed to be used to run OS X applications that are wrapped in application bundles. Launch Services doesn't recognize your program as an application, just try to run open -a VisiMacXsltConverter...

Just specify its (absolute or relative path) so it's not searched in $PATH. Either of the following will work, of course depending on your current working directory and where the program is stored:

./VisiMacXsltConverter a "b c"
/Users/rohan/Documents/VisiMacXsltConverter/VisiMacXsltConverter a "b c"

Daniel Beck

Posted 2012-05-17T08:35:35.373

Reputation: 98 421

0

To address you question - not as sure about your error:

Think a normal C/C++ "main" class as in:

int main() {}

simply replace this with

int main(int argc, char* argv[]) {}

Where you can index the arguments by argv[i]. Note that the call to the function is itself an argument (argv[0]);

A Full Example (Will Usage Message):

int main(int argc, char* argv[]){

string fileName;

if (argc < 2) { // Remind user of how to use this program
    cerr << "Usage: " << argv[0] << " filename" << endl;
    return 0;
} else {
    fileName = argv[1];
}
}

Note with this method you do not need to preface parameters with '-' on command line. You could optionally add that convention by just looking for '-' and just taking the string after it.

jds

Posted 2012-05-17T08:35:35.373

Reputation: 632

-1

argc will always hold the value of 1. Which is why the output displayed is "got 1" and then continued to the loop. Essentially since i = 0, it will print out the path of the program that is being executed, because the argv array always begins with the path at position 0. argc only holds the length of the argv array. After the first loop, the program ends and displays the correct output.

so in your case I would write:

int main(int argc, const char * argv[])
{
    std::cout << "got "<<argc<<" arguments";
    for ( int i = 1; i<=argc;i++){
        std::cout << "argument:"<<i<<"= "<<argv[i];
    }
    //// some other piece of code 
}

Surge_Protector

Posted 2012-05-17T08:35:35.373

Reputation: 1

(1) What do you mean, “argc will always hold the value of 1.”? argc is the argument count; if there are five arguments (counting argv[0]), argc should be 5. You said it yourself: “argc only holds the length of the argv array.” (thus contradicting your first sentence).  (2) Arrays in C (and related languages) begin at 0, so if the argv array has argc elements, then the last one is number argc-1. … (Cont’d) – Scott – 2017-02-03T21:10:47.990

(Cont’d) …  By telling the OP to run his loop while i<=argc, you are guaranteeing that i will eventually become equal to argc, so argv[i] will be accessing the array out of bounds.  (3) What do you mean, “After the first loop, the program ends and displays the correct output.”?  (4) Please don’t say, “so in your case I would write:” and then repeat the OP’s entire program with two tiny, one-character changes without stating what the changes are — it’s very hard to see them. – Scott – 2017-02-03T21:11:37.487