Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Process argc and argv outside of main()

If I want to keep the bulk of my code for processing command line arguments out of main (for organization and more readable code), what would be the best way to do it?

void main(int argc, char* argv[]){
    //lots of code here I would like to move elsewhere
}
like image 815
Joey Huggins Avatar asked Oct 12 '12 15:10

Joey Huggins


People also ask

Can you access argv outside of main?

As long as you don't return from main and try to process them in an atexit handler or the destructor of an object at global scope, they still exist and will be fine to access from any scope. For example: // Passing them as args: void process_command_line(int argc, char **argv) { // Use argc and argv ... }

What is argc and argv in main () functions?

The first parameter, argc (argument count) is an integer that indicates how many arguments were entered on the command line when the program was started. The second parameter, argv (argument vector), is an array of pointers to arrays of character objects.

How do you pass argc and argv in C++?

To pass command line arguments, we typically define main() with two arguments : first argument is the number of command line arguments and second is list of command-line arguments. The value of argc should be non negative. argv(ARGument Vector) is array of character pointers listing all the arguments.

How does argc and argv work in C?

argv and argc are how command line arguments are passed to main() in C and C++. argc will be the number of strings pointed to by argv . This will (in practice) be 1 plus the number of arguments, as virtually all implementations will prepend the name of the program to the array.


2 Answers

Either pass them as parameters, or store them in global variables. As long as you don't return from main and try to process them in an atexit handler or the destructor of an object at global scope, they still exist and will be fine to access from any scope.

For example:

// Passing them as args:
void process_command_line(int argc, char **argv)
{
    // Use argc and argv
    ...
}

int main(int argc, char **argv)
{
    process_command_line(argc, argv);
    ...
}

Alternatively:

// Global variables
int g_argc;
char **g_argv;

void process_command_line()
{
    // Use g_argc and g_argv
    ...
}

int main(int argc, char **argv)
{
    g_argc = argc;
    g_argv = argv;
    process_command_line();
    ...
}

Passing them as parameters is a better design, since it's encapsulated and let's you modify/substitute parameters if you want or easily convert your program into a library. Global variables are easier, since if you have many different functions which access the args for whatever reason, you can just store them once and don't need to keep passing them around between all of the different functions.

like image 150
Adam Rosenfield Avatar answered Oct 02 '22 14:10

Adam Rosenfield


One should keep to standards wherever practical. Thus, don't write

void main

which has never been valid C or C++, but instead write

int main

With that, your code can compile with e.g. g++ (with usual compiler options).

Given the void main I suspect a Windows environment. And anyway, in order to support use of your program in a Windows environment, you should not use the main arguments in Windows. They work in *nix because they were designed in and for that environment; they don't in general work in Windows, because by default (by very strong convention) they're encoded as Windows ANSI, which means they cannot encode filenames with characters outside the user's current locale.

So for Windows you better use the GetCommandLine API function and its sister parsing function. For portability this should better be encapsulated in some command line arguments module. Then you need to deal with the interesting problem of using wchar_t in Windows and char in *nix…

Anyway, I'm not sure of corresponding *nix API, or even if there is one, but google it. In the worst case, for *nix you can always initialize a command line arguments module from main. The ugliness for *nix stems directly from the need to support portability with C++'s most non-portable, OS-specific construct, namely standard main.

like image 39
Cheers and hth. - Alf Avatar answered Oct 02 '22 14:10

Cheers and hth. - Alf