Command Line Arguments in C++

When we compile and link our program, the output is an executable file. When a program is run, execution starts at the top of the function called main(). Un to this point, we have declared main like this:

int main()

Notice that this version of main() takes no parameters. However, many programs need  some kind of input to work with. For example, let's say you were writing a program called Thumbnail that read in an image file, and then produces a thumbnail (a smaller version of the image). How would Thumbnail know which image to read and process. The user has to have some way of telling the program which file to open. To do this, you might take this approach:

// Program: Thumbnail
#include <iostream>
#include <string>

int main()
{
    std::cout << "Please enter an image filename to create a thumbnail for: ";
    std::string filename{};
    std::cin >> filename;

    // open image file
    // create thumbnail
    // output thumbnail
}

However, there is a potential problem with this approach. Every time the program is run, the program will wait for the user to enter input. This may not be a problem if you are manually running this program once from the command line. But it is problematic in other cases, such as when you want to run this program on many files, or have program run by another program.

  • What if you want to create thumbnail for all the image files in a given directory.

Command Line Arguments

Command Line Arguments are optional string arguments that are passed by the operating system to the program when it is launched. The program can then use them as input. Much like function parameters provide a way for a function to provide inputs to another function, command line arguments provide a way for people or programs to provide inputs to a program.

Command line arguments are values provided to a program when it is executed from the command line or terminal.

Passing command line arguments

In Unix-based OS, we can run the compiled program as follows:

./program

In order to pass command line arguments to program, we simply list the command line arguments after the executable name:

./program my-file.txt

Now when program is executed, my-file.txt will be provided as a command line argument. A program can have multiple command line arguments, separated by spaces:

./program my-file.txt new-file.txt

Using Command Line Arguments

Now that we know how to provide command line arguments to a program, the next step is to access them from within our C++ program. To do that, we use a different form of main() than we have seen before. This new form of main() takes two arguments (named argc and argv by convention) as follows:

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

You will sometimes also see it written as:

int main(int argc, char** argv);

Even though these are treated identically, we prefer the first representation because it's intuitively easier to understand.

argc is an integer parameter containing a count of the number of arguments passed to the program (think: argc = argument count). argc will always be at least 1, because the first argument is always the name of the program itself. Each command line argument the user provides will cause argc to increase by 1.

argv is where the actual argument values are stored (think: argv = argument values, though the proper name is “argument vectors”). Although the declaration of argv looks intimidating, argv is really just an array of char pointers (each of which points to a C-style string). The length of this array is argc.

Let's write a short program named “MyArgs” to print the value of all the command line parameters:

// Program: MyArgs
#include <iostream>

int main(int argc, char* argv[])
{
    std::cout << "There are " << argc << " arguments:\n";

    // Loop through each argument and print its number and value
    for (int count{ 0 }; count < argc; ++count)
    {
        std::cout << count << ' ' << argv[count] << '\n';
    }

    return 0;
}

Now, when we invoke this program (MyArgs) with the command line arguments  “Myfile.txt” and “7”, the output will be as follows:

There are 3 arguments:
0 MyArgs
1 Myfile.txt
2 7
  • Argument 0 is the path and name of the current program being run.
  • Argument 1 and 2 in this case are the two command line parameters we passed in.

Dealing with numeric arguments

Command line arguments are always passed as strings, even if the value provided is numeric in nature. To use a command line argument as a number, you must convert it from a string to a number. Unfortunately, C++ makes this a little more difficult than it should be.

#include <iostream>
#include <sstream> // for std::stringstream
#include <string>

int main(int argc, char* argv[])
{
	if (argc <= 1)
	{
		// On some operating systems, argv[0] can end up as an empty string instead of the program's name.
		// We'll conditionalize our response on whether argv[0] is empty or not.
		if (argv[0])
			std::cout << "Usage: " << argv[0] << " <number>" << '\n';
		else
			std::cout << "Usage: <program name> <number>" << '\n';

		return 1;
	}

	std::stringstream convert{ argv[1] }; // set up a stringstream variable named convert, initialized with the input from argv[1]

	int myint{};
	if (!(convert >> myint)) // do the conversion
		myint = 0; // if conversion fails, set myint to a default value

	std::cout << "Got integer: " << myint << '\n';

	return 0;
}

// Output
Got integer: 7

std::stringstream works much like std::cin. In this case, we are initializing it with the value of argv[1], so that we can use operator >> to extract the value to an integer variable.

The OS parses command line arguments first

When you type something at the command line, it is the operating system's responsibility to translate and route that request as appropriate. This not only involves running the executable, it also involves parsing any arguments to determine how they should be handled and passed to the application.

Generally, operating systems have special rules about how special characters like double quotes and backslashed are handled.

For Example:

MyArgs Hello world

Prints:

There are 3 arguments:
0 MyArgs
1 Hello
2 world

Typically, strings passed in double quotes are considered to be part of the same string:

MyArgs "Hello world"

Prints:

There are 2 arguments:
0 MyArgs
1 Hello world

Most Operating System allow you to include a literal double quote by backslashing the double quote:

MyArgs \"Hello world\"

Prints:

There are 3 aruments
0 MyArgs
1 "Hello
2 world"