1.12.1.  main, and Command Line Arguments

[ fromfile: clargs.xml id: clargs ]

main() is a function (Chapter 5) that is called at program startup. If we wish the program to accept command line arguments, we must define main with its full parameter list.

C and C++ permit some flexibility in the way that arguments are defined in main(), so you may see it defined in a variety of ways:

int main(int argc, char* argv[])
int main(int argCount, char ** argValues)
int main(int argc, char * const argv[])

All of the above forms are valid, and they each define two parameters: an int to contain the number of command line arguments and an array of C-style strings to contain the actual arguments. These parameters contain enough information to reconstruct the command line arguments passed into the program from the parent process [8]. Example 1.16 is a simple main program which prints its command line arguments.

Example 1.16. src/clargs/iostream/clargs.cpp

#include <iostream>
#include <cstdlib>  1

int main (int argc, char* argv[]) {
    using namespace std;
    cout << "argc = " << argc << endl;
    for (int i = 0; i < argc; ++i) {
        cout << "argv# " << i << " is " << argv[i] << endl;
    }
    int num = atoi(argv[argc - 1]);
    cout << num * 2 << endl;
    return 0;
}

1

for atoi()

argv, the argument vector, is an array (Section 22.4) that contains all of the command line strings. In other words, since each individual command line string is itself an array of char, argv is an array of char arrays. argc, the argument count, is the number of char arrays in argv.

main() needs to return an int to the parent process. The return value should be 0, if all went well, or a non-zero error code if something went wrong. This can be accomplished in a few different ways.

[Note]Note

Try not to confuse this interpretation of 0 with the bool value false, which is also equal to zero.

If we run this program with command line arguments, we will see something like this in the output:

clargs> ./clargs spam eggs "space wars" 123
argc = 5
argv# 0 is ./clargs
argv# 1 is spam
argv# 2 is eggs
argv# 3 is space wars
argv# 4 is 123
246

The first argument is the name of the executable. The other arguments are taken from the command line as strings separated by spaces or tabs. To pass a string that contains spaces as a single argument, you must enclose the string in quotes.

The last argument looks like the number 123. In fact, it is the string representation of that number. If we need to calculate with that number, it would be necessary to use a suitable function to convert the string “123” to the number 123.

Processing Command Line Arguments with Qt

In example Example 1.17, we have rewritten Example 1.16 to set up and access the command line arguments using Qt 4 types and avoiding the use of arrays. The two apps produce the same output.

Example 1.17. src/clargs/qt/clargs.cpp

#include <QTextStream>
#include <QCoreApplication>
#include <QStringList>

int main (int argc, char* argv[]) {
    QCoreApplication app(argc, argv);
    QTextStream cout(stdout, QIODevice::WriteOnly);
    QStringList arglst = app.arguments();
    cout << "argc = " << argc << endl;
    for (int i=0; i<arglst.size(); ++i) {
        cout << QString("argv#%1 is %2").arg(i).arg(arglst[i]) << endl;
    }
    int num = arglst[argc - 1].toInt();
    cout << num * 2 << endl;
}


Most applications that employ Qt types should define an object of type QCoreApplication or QApplication as early as possible in main(). [9] We will discuss the reasons for this and the distinctions between those two types in more detail in Section 9.3.

We initialize the the QCoreApplication, app with the argument count and the argument vector. app silently converts the char arrays in argv to QStrings and stores those strings in a QStringList (Section 4.2.1 We can then access and process the command line arguments by using app to call the arguments() function. Using higher level data structures like these eliminates the need to work with char arrays, which reduces the risk of memory corruption. [10]

Notice the use of the QString function toInt().



[8] The process that called main() (e.g., a command line shell, a window manager, etc)

[9] Apps that use only types such as QString, QStringList, and QTextStream do not need a QCoreApplication.

[10] First read Section 1.14 then Chapter 22. Bjarne Stroustrup also has some helpful advice on this subject.