[ fromfile: argumentlist.xml id: argumentlist ]
ArgumentList provides an example of a reusable class with a specific purpose derived from a more general purpose Qt class. It reuses QString and QStringList to simplify the processing of command-line arguments.
Operationally, ArgumentList is
a class that is initialized with the main()
function's int
and char**
parameters, which capture the
command-line arguments.
Conceptually, ArgumentList
is a list of QString
s.
Structurally, it is derived from QStringList, with some added
functionality.
A Java programmer would say that ArgumentList
is extended from QStringList.
Example 6.26 contains the class
definition for ArgumentList
.
Example 6.26. src/derivation/argumentlist/argumentlist.h
#ifndef ARGUMENTLIST_H #define ARGUMENTLIST_H #include <QStringList> class ArgumentList : public QStringList { public: ArgumentList(); ArgumentList(int argc, char* argv[]) { argsToStringlist(argc, argv); } ArgumentList(const QStringList& argumentList): QStringList(argumentList) {} bool getSwitch(QString option); QString getSwitchArg(QString option, QString defaultRetVal=QString()); private: void argsToStringlist(int argc, char* argv[]); }; #endif
Because it is publicly derived from QStringList, ArgumentList
supports the full interface of QStringList and can be used
wherever a QStringList is expected.
In addition to its constructors, ArgumentList
defines a few additional functions:
argsToStringList()
extracts the command-line arguments from the given
array of char
arrays and loads them into a QStringList. This
function is private
because it is part of the implementation of this
class, not part of the public interface. It is needed by the constructors but not by client code.
getSwitch()
finds and removes a switch from the string list, if that
switch exists. It returns true
if the switch is found and false
otherwise.
getSwitchArg()
finds and removes a switch and its accompanying argument
from the string list and returns the argument if the switch is found. It does nothing and returns a
defaultValue
if the switch is not found.
Example 6.27 shows the implementation code for these functions.
Example 6.27. src/derivation/argumentlist/argumentlist.cpp
#include <QCoreApplication> #include <QDebug> #include "argumentlist.h" ArgumentList::ArgumentList() { if (qApp != NULL) *this = qApp->arguments(); } void ArgumentList::argsToStringlist(int argc, char * argv []) { for (int i=0; i < argc; ++i) { *this += argv[i]; } } bool ArgumentList::getSwitch (QString option) { QMutableStringListIterator itr(*this); while (itr.hasNext()) { if (option == itr.next()) { itr.remove(); return true; } } return false; } QString ArgumentList::getSwitchArg(QString option, QString defaultValue) { if (isEmpty()) return defaultValue; QMutableStringListIterator itr(*this); while (itr.hasNext()) { if (option == itr.next()) { itr.remove(); if (itr.hasNext()) { QString retval = itr.next(); itr.remove(); return retval; } else { qDebug() << "Missing Argument for " << option; return QString(); } } } return defaultValue; }
A global pointer to the current QApplication. |
In the client code shown in Example 6.28
all argument processing code has been removed from main()
.
No loops, char*
, or strcmp
are to be found.
Example 6.28. src/derivation/argumentlist/main.cpp
#include <QString> #include <QDebug> #include "argumentlist.h" void processFile(QString filename, bool verbose) { if (verbose) qDebug() << QString("Do something chatty with %1.") .arg(filename); else qDebug() << filename; } void runTestOnly(QStringList & listOfFiles, bool verbose) { foreach (const QString ¤t, listOfFiles) { processFile(current, verbose); } } int main( int argc, char * argv[] ) { ArgumentList al(argc, argv); QString appname = al.takeFirst(); qDebug() << "Running " << appname; bool verbose = al.getSwitch("-v"); bool testing = al.getSwitch("-t"); if (testing) { runTestOnly(al, verbose); return 0; } else { qDebug() << "This Is Not A Test"; } }
Instantiate the ArgumentList with command line args. |
|
Inherited from QStringList - first item in the list is the name of the executable. |
|
Now all switches have been removed from the list. Only filenames remain. |
|
ArgumentList can be used in place of QStringList. |
Following are some sample outputs from running the program in Example 6.28:
argumentlist> ./argumentlist Running "./argumentlist" This Is Not A Test argumentlist> ./argumentlist item1 "item2 item3" item4 item5 Running "./argumentlist" This Is Not A Test argumentlist> ./argumentlist -v -t "foo bar" 123 space1 "1 1" Running "./argumentlist" "Do something chatty with foo bar." "Do something chatty with 123." "Do something chatty with space1." "Do something chatty with 1 1." argumentlist>
Generated: 2012-03-02 | © 2012 Alan Ezust and Paul Ezust. |