[ 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
<include src="src/derivation/argumentlist/argumentlist.h" href="src/derivation/argumentlist/argumentlist.h" id="ex-arglisth" mode="cpp"/>
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; }
<include src="src/derivation/argumentlist/argumentlist.cpp" href="src/derivation/argumentlist/argumentlist.cpp" id="ex-arglistcpp" mode="cpp"/>
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"; } }
<include src="src/derivation/argumentlist/main.cpp" href="src/derivation/argumentlist/main.cpp" id="arglist-client" mode="cpp"/>
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. |