Related
In many C++ IDE's and compilers, when it generates the main function for you, it looks like this:
int main(int argc, char *argv[])
When I code C++ without an IDE, just with a command line compiler, I type:
int main()
without any parameters. What does this mean, and is it vital to my program?
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.
The variables are named argc (argument count) and argv (argument vector) by convention, but they can be given any valid identifier: int main(int num_args, char** arg_strings) is equally valid.
They can also be omitted entirely, yielding int main(), if you do not intend to process command line arguments.
Try the following program:
#include <iostream>
int main(int argc, char** argv) {
std::cout << "Have " << argc << " arguments:" << std::endl;
for (int i = 0; i < argc; ++i) {
std::cout << argv[i] << std::endl;
}
}
Running it with ./test a1 b2 c3 will output
Have 4 arguments:
./test
a1
b2
c3
argc is the number of arguments being passed into your program from the command line and argv is the array of arguments.
You can loop through the arguments knowing the number of them like:
for(int i = 0; i < argc; i++)
{
// argv[i] is the argument at index i
}
Suppose you run your program thus (using sh syntax):
myprog arg1 arg2 'arg 3'
If you declared your main as int main(int argc, char *argv[]), then (in most environments), your main() will be called as if like:
p = { "myprog", "arg1", "arg2", "arg 3", NULL };
exit(main(4, p));
However, if you declared your main as int main(), it will be called something like
exit(main());
and you don't get the arguments passed.
Two additional things to note:
These are the only two standard-mandated signatures for main. If a particular platform accepts extra arguments or a different return type, then that's an extension and should not be relied upon in a portable program.
*argv[] and **argv are exactly equivalent, so you can write int main(int argc, char *argv[]) as int main(int argc, char **argv).
int main();
This is a simple declaration. It cannot take any command line arguments.
int main(int argc, char* argv[]);
This declaration is used when your program must take command-line arguments. When run like such:
myprogram arg1 arg2 arg3
argc, or Argument Count, will be set to 4 (four arguments), and argv, or Argument Vectors, will be populated with string pointers to "myprogram", "arg1", "arg2", and "arg3". The program invocation (myprogram) is included in the arguments!
Alternatively, you could use:
int main(int argc, char** argv);
This is also valid.
There is another parameter you can add:
int main (int argc, char *argv[], char *envp[])
The envp parameter also contains environment variables. Each entry follows this format:
VARIABLENAME=VariableValue
like this:
SHELL=/bin/bash
The environment variables list is null-terminated.
IMPORTANT: DO NOT use any argv or envp values directly in calls to system()! This is a huge security hole as malicious users could set environment variables to command-line commands and (potentially) cause massive damage. In general, just don't use system(). There is almost always a better solution implemented through C libraries.
The parameters to main represent the command line parameters provided to the program when it was started. The argc parameter represents the number of command line arguments, and char *argv[] is an array of strings (character pointers) representing the individual arguments provided on the command line.
The main function can have two parameters, argc and argv. argc is an integer (int) parameter, and it is the number of arguments passed to the program.
The program name is always the first argument, so there will be at least one argument to a program and the minimum value of argc will be one. But if a program has itself two arguments the value of argc will be three.
Parameter argv points to a string array and is called the argument vector. It is a one dimensional string array of function arguments.
Lets consider the declaration:
int main (int argc, char *argv[])
In the above declaration, the type of the second parameter named argv is actually a char**. That is, argv is a pointer to a pointer to a char. This is because a char* [] decays to a char** due to type decay. For example, the below given declarations are equivalent:
int main (int argc, char *argv[]); //first declaration
int main (int argc, char **argv); //RE-DECLARATION. Equivalent to the above declaration
In other words, argv is a pointer that points to the first element of an array with elements of type char*. Moreover, each elements argv[i] of the array(with elements of type char*) itself point to a character which is the start of a null terminated character string. That is, each element argv[i] points to the first element of an array with elements of type char(and not const char). A diagram is given for illustration purposes:
As already said in other answers, this form of declaration of main is used when we want to make use of the command line argument(s).
The first parameter is the number of arguments provided and the second parameter is a list of strings representing those arguments.
Both of
int main(int argc, char *argv[]);
int main();
are legal definitions of the entry point for a C or C++ program. Stroustrup: C++ Style and Technique FAQ details some of the variations that are possible or legal for your main function.
In case you learn something from this
#include<iostream>
using namespace std;
int main(int argc, char** argv) {
cout << "This program has " << argc << " arguments:" << endl;
for (int i = 0; i < argc; ++i) {
cout << argv[i] << endl;
}
return 0;
}
This program has 3 arguments. Then the output will be like this.
C:\Users\user\Desktop\hello.exe
hello
people
When using int and char**, the first argument will be the number of commands in by which the programs is called and second one is all those commands
Just to add because someone says there is a third parameter (*envp[]), it's true, there is, but is not POSIX safe, if you want your program to use environment variables you should use extern char environ ;D
Basically I am working on integrating an existing C++ file with our javascript / node using their NAPI, functionality. I have it working on a test C++ file so I know I have the setup working. However on the actual C++ file it is designed to run from the command line with argc and argv from the command line. Basically I just need to invoke the main method in C++ from inside of my other function, which means there is no command line. So I have to pass in values for argc and argv. argc is just an int, that is easy enough, but argc is a char ** type, which from my research looks like it is an array of character arrays aka strings?
This is my current code at the bottom of my c++ file
void Init(Env env, Object exports, Object module) {
exports.Set("main", Function::New(env, main(2,{"test","test2"})));
}
NODE_API_MODULE(addon, Init)
The argc value is working fine
I am trying to create a temporary / test value for argv to pass in but I am having an issue figuring out how to make an array of type char ** with my values.
argv is an array of pointers to strings (actually, NUL-terminated character arrays), where element 0 is the name of the program, elements 1 ... argc-1 are the program arguments, and element argc must be NULL1.
There's no array literal in C++, so you have to create explicitly an array variable to pass it to a function. Even worse, main is allowed to modify the passed arguments, so you cannot even build an array of string literals, as they are read only; thus, you have to explicitly allocate read/write space for each argument. A barebones solution can be to have single buffers for each argument and build the pointer array out of them:
char argv0[] = "test_program";
char argv1[] = "arg1";
char argv2[] = "arg2";
char *argv[] = {argv0, argv1, argv2, NULL};
main(3, argv);
A more flexible one (especially if you have to build your arguments dynamically) can be to use an std::vector<std::string>:
std::vector<std::string> args = { "test_program", "arg1", "arg2" };
// ... here you may add other arguments dynamically...
args.push_back("arg3"); // whatever
// build the pointers array
std::vector<char *> argv;
for(std::string &s: args) argv.push_back(&s[0]);
argv.push_back(NULL);
main(argv.size()-1, argv.data());
Now, coming to your code:
void Init(Env env, Object exports, Object module) {
exports.Set("main", Function::New(env, main(2,{"test","test2"})));
}
NODE_API_MODULE(addon, Init)
besides the fact that you cannot build argv to pass to main like that, you are trying to invoke main and pass its result as second argument to Function::New, while Function::New wants some callable type (e.g. a function pointer) to register as handler for the export named main! Copying from the Function::New documentation:
/// Callable must implement operator() accepting a const CallbackInfo&
/// and return either void or Value.
So, as a simple example, you could export your main as a parameterless JS function that returns nothing (undefined, I guess?) by registering a callback like this:
void MainCallback(const CallbackInfo& info) {
char argv0[] = "test_program";
char argv1[] = "arg1";
char argv2[] = "arg2";
char *argv[] = {argv0, argv1, argv2, NULL};
main(3, argv);
}
void Init(Env env, Object exports, Object module) {
exports.Set("main", Function::New(env, MainCallback));
}
NODE_API_MODULE(addon, Init)
Finally, as others said, technically in C++ main is somewhat magic - it's undefined behavior to invoke it from inside the program; in practice, on any platform that I know of that can also run node.js, main is a perfectly regular function that happens to be invoked by the C runtime at startup, so I don't think that this will cause you any problem.
Notes
So, you could say it's a NULL-terminated array of NUL-terminated character arrays. Notice that here NULL = null pointer; NUL = string terminator, i.e. '\0'.
I'm looking for alternative ways to obtain the command line parameters argc and argv provided to a process without having direct access to the variables passed into main().
I want to make a class that is independent of main() so that argc and argv don't have to be passed explicitly to the code that uses them.
EDIT: Some clarification seems to be in order. I have this class.
class Application
{
int const argc_;
char const** const argv_;
public:
explicit Application(int, char const*[]);
};
Application::Application(int const argc, char const* argv[]) :
argc_(argc),
argv_(argv)
{
}
But I'd like a default constructor Application::Application(), with some (most probably) C code, that pulls argc and argv from somewhere.
On Linux, you can get this information from the process's proc file system, namely /proc/$$/cmdline:
int pid = getpid();
char fname[PATH_MAX];
char cmdline[ARG_MAX];
snprintf(fname, sizeof fname, "/proc/%d/cmdline", pid);
FILE *fp = fopen(fname);
fgets(cmdline, sizeof cmdline, fp);
// the arguments are in cmdline
The arguments to main are defined by the C runtime, and the only standard/portable way to obtain the command line arguments. Don't fight the system. :)
If all you want to do is to provide access to command line parameters in other parts of the program with your own API, there are many ways to do so. Just initialise your custom class using argv/argc in main and from that point onward you can ignore them and use your own API. The singleton pattern is great for this sort of thing.
To illustrate, one of the most popular C++ frameworks, Qt uses this mechanism:
int main(int argc, char* argv[])
{
QCoreApplication app(argc, argv);
std::cout << app.arguments().at(0) << std::endl;
return app.exec();
}
The arguments are captured by the app and copied into a QStringList. See QCoreApplication::arguments() for more details.
Similarly, Cocoa on the Mac has a special function which captures the command line arguments and makes them available to the framework:
#import <Cocoa/Cocoa.h>
int main(int argc, char *argv[])
{
return NSApplicationMain(argc, (const char **)argv);
}
The arguments are then available anywhere in the app using the NSProcessInfo.arguments property.
I notice in your updated question that your class directly stores a copy of argc/argv verbatim in its instance:
int const argc_;
char const** const argv_;
While this should be safe (the lifetime of the argv pointers should be valid for the full lifetime of the process), it is not very C++-like. Consider creating a vector of strings (std::vector<std::string>) as a container and copy the strings in. Then they can even be safely mutable (if you want!).
I want to make a class that is independent of main() so that argc and argv don't have to be passed explicitly to the code that uses them.
It is not clear why passing this info from main is somehow a bad thing that is to be avoided. This is just how the major frameworks do it.
I suggest you look at using a singleton to ensure there is only one instance of your Application class. The arguments can be passed in via main but no other code need know or care that this is where they came from.
And if you really want to hide the fact that main's arguments are being passed to your Application constructor, you can hide them with a macro.
To answer the question in part, concerning Windows, the command line can be obtained as the return of the GetCommandLine function, which is documented here, without explicit access to the arguments of the main function.
I totally agree with #gavinb and others. You really should use the arguments from main and store them or pass them where you need them. That's the only portable way.
However, for educational purposes only, the following works for me with clang on OS X and gcc on Linux:
#include <stdio.h>
__attribute__((constructor)) void stuff(int argc, char **argv)
{
for (int i=0; i<argc; i++) {
printf("%s: argv[%d] = '%s'\n", __FUNCTION__, i, argv[i]);
}
}
int main(int argc, char **argv)
{
for (int i=0; i<argc; i++) {
printf("%s: argv[%d] = '%s'\n", __FUNCTION__, i, argv[i]);
}
return 0;
}
which will output:
$ gcc -std=c99 -o test test.c && ./test this will also get you the arguments
stuff: argv[0] = './test'
stuff: argv[1] = 'this'
stuff: argv[2] = 'will'
stuff: argv[3] = 'also'
stuff: argv[4] = 'get'
stuff: argv[5] = 'you'
stuff: argv[6] = 'the'
stuff: argv[7] = 'arguments'
main: argv[0] = './test'
main: argv[1] = 'this'
main: argv[2] = 'will'
main: argv[3] = 'also'
main: argv[4] = 'get'
main: argv[5] = 'you'
main: argv[6] = 'the'
main: argv[7] = 'arguments'
The reason is because the stuff function is marked as __attribute__((constructor)) which will run it when the current library is loaded by the dynamic linker. That means in the main program it will run even before main and have a similar environment. Therefore, you're able to get the arguments.
But let me repeat: This is for educational purposes only and shouldn't be used in any production code. It won't be portable and might break at any point in time without warning.
In Windows, if you need to get the arguments as wchar_t *, you can use CommandLineToArgvW():
int main()
{
LPWSTR *sz_arglist;
int n_args;
int result;
sz_arglist = CommandLineToArgvW(GetCommandLineW(), &n_args);
if (sz_arglist == NULL)
{
fprintf(stderr, _("CommandLineToArgvW() failed.\n"));
return 1;
}
else
{
result = wmain(n_args, sz_arglist);
}
LocalFree(sz_arglist);
return result;
}
This is very convenient when using MinGW because gcc does not recognize int _wmain(int, wchar_t *) as a valid main prototype.
Passing values doesn't constitute creating a dependency. Your class doesn't care about where those argc or argv values come out of - it just wants them passed. You may want to copy the values somewhere, though - there's no guarantee that they are not changed (the same applies to alternate methods like GetCommandLine).
Quite the opposite, in fact - you're creating a hidden dependency when you use something like GetCommandLine. Suddenly, instead of a simple "pass a value" semantics, you have "magically take their inputs from elsewhere" - combined with the aforementioned "the values can change at any time", this makes your code a lot more brittle, not to mention impossible to test. And parsing command line arguments is definitely one of the cases where automated testing is quite beneficial. It's a global variable vs. a method argument approach, if you will.
In C/C++, if main() doesn't export them, then there isn't a direct way to access them; however, that doesn't mean there isn't an indirect way. Many Posix-like systems use the elf format which passes argc, argv and envp on the stack in order to be initialized by _start() and passed into main() via normal calling convention. This is typically done in assembly (because there is still no portable way to get the stack pointer) and put in a "start file", typically with some variation of the name crt.o.
If you don't have access to main() so that you can just export the symbols, you probably aren't going to have access to _start(). So why then, do I even mention it? Because of that 3rd parameter envp. Since environ is a standard exported variable that does get set during _start() using envp. On many ELF systems, if you take the base address of environ and walk it backwards using negative array indices you can deduce the argc and argv parameters. The first one should be NULL followed by the last argv parameter until you get to the first. When the pointed to value cast to long is equal to the negative of your negative index, you have argc and the next (one more than your negative index) is argv/argv[0].
There are few common scenarios with functions requiring arguments of type int argc, char *argv[] known to me. One such obvious example is GLUT, where its initializing function is taking over these arguments from main(), which is kind of "nested main" scenario. This may or may not be your desired behavior. If not, as there is no convention for naming these arguments, as long as your function has its argument parser, and you know what you're doing, you can do whatever you need, hardcoded:
int foo = 1;
char * bar[1] = {" "};
or read from user input or generated otherwise, AFAIK.
int myFunc( int foo, char *bar[]){
//argument parser
{… …}
return 0;
}
Please, see this SO post.
The most portable way would be to use a global variable for storing the parameters. You can make this less ugly by using a Singleton (like your class in the question, but a singleton initialized by main) or similar a Service Locator which is basically just the same: Create an object in main, pass and store params statically, and have another or the same class access them.
Non-Portable ways are using GetCommandLine in Windows, accessing /proc/<pid>/cmdline or (/proc/self/cmdline), or using compiler-specific extensions like __attribute__((constructor))
Note that getting the command line in function via an equivalent of GetCommandLine is not possible (TLDR: Commandline is not passed to the Linux kernel, but already parsed and split by the invoking process (e.g. shell))
Here is a proper c++ way of doing so:
#include <iostream>
#include <fstream>
#include <unistd.h>
#include <sstream>
#include <vector>
using namespace std;
template <typename T>
string to_str(T value ){
ostringstream ss;
ss << value;
return ss.str();
}
int main(int argc, char** argv){
ifstream reader("/proc/" + to_str(getpid()) + "/cmdline", ios::binary);
vector<unsigned char> buffer(istreambuf_iterator<char>(reader), {});
int length = buffer.size();
for(int i = 0; i < length; i++){
if(!buffer[i]){
cout << endl;
}else{cout << buffer[i];}
}
return 0;
}
It sounds like what you want is a global variable; what you should do is just pass argc and argv as parameters.
An instructor had a challenge to use the gcc option nostartfiles and then try to access argc and argv. The nostartfiles option causes argc and argv to not be populated. This was my best solution for 64 bit Linux as it accesses argc and argv directly using the base pointer:
// Compile with gcc -nostartfiles -e main args.c -o args
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) // argc and argv are not available when compiled with -nostartfiles
{
register void *rbp asm ("rbp");
printf("argc is %ld\n", *(unsigned long *)(rbp + 8));
for(int count = 0 ; count < *(unsigned long *)(rbp + 8) ; count++)
{
printf("argv[%d] is %s\n", count, *(char **)(rbp + 16 + count * 8));
}
exit(0);
}
In many C++ IDE's and compilers, when it generates the main function for you, it looks like this:
int main(int argc, char *argv[])
When I code C++ without an IDE, just with a command line compiler, I type:
int main()
without any parameters. What does this mean, and is it vital to my program?
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.
The variables are named argc (argument count) and argv (argument vector) by convention, but they can be given any valid identifier: int main(int num_args, char** arg_strings) is equally valid.
They can also be omitted entirely, yielding int main(), if you do not intend to process command line arguments.
Try the following program:
#include <iostream>
int main(int argc, char** argv) {
std::cout << "Have " << argc << " arguments:" << std::endl;
for (int i = 0; i < argc; ++i) {
std::cout << argv[i] << std::endl;
}
}
Running it with ./test a1 b2 c3 will output
Have 4 arguments:
./test
a1
b2
c3
argc is the number of arguments being passed into your program from the command line and argv is the array of arguments.
You can loop through the arguments knowing the number of them like:
for(int i = 0; i < argc; i++)
{
// argv[i] is the argument at index i
}
Suppose you run your program thus (using sh syntax):
myprog arg1 arg2 'arg 3'
If you declared your main as int main(int argc, char *argv[]), then (in most environments), your main() will be called as if like:
p = { "myprog", "arg1", "arg2", "arg 3", NULL };
exit(main(4, p));
However, if you declared your main as int main(), it will be called something like
exit(main());
and you don't get the arguments passed.
Two additional things to note:
These are the only two standard-mandated signatures for main. If a particular platform accepts extra arguments or a different return type, then that's an extension and should not be relied upon in a portable program.
*argv[] and **argv are exactly equivalent, so you can write int main(int argc, char *argv[]) as int main(int argc, char **argv).
int main();
This is a simple declaration. It cannot take any command line arguments.
int main(int argc, char* argv[]);
This declaration is used when your program must take command-line arguments. When run like such:
myprogram arg1 arg2 arg3
argc, or Argument Count, will be set to 4 (four arguments), and argv, or Argument Vectors, will be populated with string pointers to "myprogram", "arg1", "arg2", and "arg3". The program invocation (myprogram) is included in the arguments!
Alternatively, you could use:
int main(int argc, char** argv);
This is also valid.
There is another parameter you can add:
int main (int argc, char *argv[], char *envp[])
The envp parameter also contains environment variables. Each entry follows this format:
VARIABLENAME=VariableValue
like this:
SHELL=/bin/bash
The environment variables list is null-terminated.
IMPORTANT: DO NOT use any argv or envp values directly in calls to system()! This is a huge security hole as malicious users could set environment variables to command-line commands and (potentially) cause massive damage. In general, just don't use system(). There is almost always a better solution implemented through C libraries.
The parameters to main represent the command line parameters provided to the program when it was started. The argc parameter represents the number of command line arguments, and char *argv[] is an array of strings (character pointers) representing the individual arguments provided on the command line.
The main function can have two parameters, argc and argv. argc is an integer (int) parameter, and it is the number of arguments passed to the program.
The program name is always the first argument, so there will be at least one argument to a program and the minimum value of argc will be one. But if a program has itself two arguments the value of argc will be three.
Parameter argv points to a string array and is called the argument vector. It is a one dimensional string array of function arguments.
Lets consider the declaration:
int main (int argc, char *argv[])
In the above declaration, the type of the second parameter named argv is actually a char**. That is, argv is a pointer to a pointer to a char. This is because a char* [] decays to a char** due to type decay. For example, the below given declarations are equivalent:
int main (int argc, char *argv[]); //first declaration
int main (int argc, char **argv); //RE-DECLARATION. Equivalent to the above declaration
In other words, argv is a pointer that points to the first element of an array with elements of type char*. Moreover, each elements argv[i] of the array(with elements of type char*) itself point to a character which is the start of a null terminated character string. That is, each element argv[i] points to the first element of an array with elements of type char(and not const char). A diagram is given for illustration purposes:
As already said in other answers, this form of declaration of main is used when we want to make use of the command line argument(s).
The first parameter is the number of arguments provided and the second parameter is a list of strings representing those arguments.
Both of
int main(int argc, char *argv[]);
int main();
are legal definitions of the entry point for a C or C++ program. Stroustrup: C++ Style and Technique FAQ details some of the variations that are possible or legal for your main function.
In case you learn something from this
#include<iostream>
using namespace std;
int main(int argc, char** argv) {
cout << "This program has " << argc << " arguments:" << endl;
for (int i = 0; i < argc; ++i) {
cout << argv[i] << endl;
}
return 0;
}
This program has 3 arguments. Then the output will be like this.
C:\Users\user\Desktop\hello.exe
hello
people
When using int and char**, the first argument will be the number of commands in by which the programs is called and second one is all those commands
Just to add because someone says there is a third parameter (*envp[]), it's true, there is, but is not POSIX safe, if you want your program to use environment variables you should use extern char environ ;D
Hi I am relatively new to programing.
I want to create a C++ program that when you call it in CMD you can pass it variables.
For example in cmd
Myprograme.exe 11 32 232
So that it uses these values in the calculation.
C++
int main(float A, float B, float C){
float sum= A+B+C;
cout << sum;
return 0;
}
My problem is I don’t know what you would call this process to even Google it.
The standard signature of main is as follows:
int main(int argc, const char **argv)
argc is the number of comman-line arguments that were given to the program (including argument number 0 which is the program's name).
argv is an array of nul-terminated character strings, each of which contains the appropriate command-line argument. argv[argc] is a null pointer.
You can use these to parse the command-line arguments an pass them on to your computation.
For example, if you issue the following on the command line:
myprog.exe a bb c
argc will be 4
argv[0] will be "myprog.exe"
argv[1] will be "a"
argv[2] will be "bb"
argv[3] will be "c"
argv[4] will be the null pointer
The main method can have two arguments :
int main(int argc, char** argv)
{
}
argc is the number of arguments, and argv is an array of char* containing the value of each argument. You can then convert you char* to float as you want. Take care, the first argument is the name of the program itself.
You always have a main function like
int main(int argc, char **argv)
{
}
The first argument is the number of arguments, argv points to argc char*s which are the arguments. This means you get char-arrays instead of floats which is absolutely understandable because you might also write
Myprograme.exe a b cde fg
See Converting char* to float or double for how to convert char* to float.
#danial weaber this is a very good example, but it does not run to the right sum. That is because it is not finding c.
Your example could should be:
#include <iostream>
using namespace std;
int main(int argc, char** argv)
{
float sum,a,b,c;
sum=atof(argv[0]);
a=atof(argv[1]);
b=atof(argv[2]);
c=atof(argv[3]);
sum=a+b+c;
cout<<sum;
}
Just wanted to point that out, so that when they run it with...
Myprograme.exe 11 32 232 it will then return 275.
Also, some ide's may not run your code correctly.
A lot of times using notepadd++ then compiling your
code in the command line, you may get the correct results. Good Luck
Answer to your first question.
This is called command line argumants.
You can use this keyword to google for it.
This is what you tried to do. First define the main function like this.
int main(int argc, char *argv[]) {
float sum,a,b,c;
a=atof(argv[0]);
b=atof(argv[1]);
c=atof(argv[2]);
sum=a+b+c;
cout<<sum;
}
Now you can pass the arguments Myprograme.exe 11 32 232 it will return 275