Ответ 1
Так как Qt 5.2 вы можете наконец найти решение в самом QtCore: я внедрил QCommandLineParser.
Я ищу синтаксический анализатор командной строки для Qt4.
Я сделал небольшой поиск в Google и нашел это: http://www.froglogic.com/pg?id=PublicationsFreeware&category=getopt, однако ему не хватает поддержки "--enable-foo" и "--enable-foo", --disable-foo ". Кроме того, он выглядит как настоящий победитель.
EDIT:
Кажется, Frologic удалил это. Поэтому лучшие варианты, которые я вижу, используют Boost (который не является API или стабильным ABI) или не поддерживают поддержку kdelib. Yay...
Так как Qt 5.2 вы можете наконец найти решение в самом QtCore: я внедрил QCommandLineParser.
QCoreApplication
конструкторы требуют (int &argc, char **argv)
(и QApplication
наследует от QCoreApplication
). Поскольку документация, настоятельно рекомендуется
Поскольку QApplication также имеет дело с общими аргументами командной строки, обычно рекомендуется создать его до того, как всякая интерпретация или модификация
argv
выполняется в самом приложении.
И если вы дадите Qt получить первый проход при обработке аргументов, также было бы неплохо использовать QStringList QCoreApplication::arguments()
вместо прохода через argv
; QApplication
может удалить некоторые из аргументов, которые он принял для собственного использования.
Это не поддается согласованию с другими библиотеками разбора аргументов...
Однако kdelibs приходит с хорошим парсером аргументов, KCmdLineArgs
. Это LGPL и может использоваться без KApplication
, если вы действительно хотите (назовите KCmdLineArgs::init
).
KCmdLineOptions options;
options.add("enable-foo", ki18n("enables foo"));
options.add("nodisable-foo", ki18n("disables foo"));
// double negatives are confusing, but this makes disable-foo enabled by default
KCmdLineArgs::addCmdLineOptions(options);
KApplication app;
KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
if (args->isSet("enable-foo") && !args->isSet("disable-foo"))
cout << "foo enabled" << endl;
else
cout << "foo disabled" << endl;
Не проиндексирован (кто когда-либо проверяет, что они публикуют на S.O.?).
Это более или менее тот же ответ, что и эфемерный, но с простым регулярным выражением, чтобы помочь разобрать аргументы. (Этот способ может быть полезен, если вам нужно только несколько аргументов)
Запустите с этим:
./QArgTest --pid=45 --enable-foo
И код:
int main(int argc, char *argv[]) {
QApplication app(argc, argv, false);
qDebug() << "QApp arg test app";
QStringList args = app.arguments();
int pid = 0;
QRegExp rxArgPid("--pid=([0-9]{1,})");
QRegExp rxArgFooEna("--enable-foo");
QRegExp rxArgFooDis("--disable-foo");
for (int i = 1; i < args.size(); ++i) {
if (rxArgPid.indexIn(args.at(i)) != -1 ) {
pid = rxArgPid.cap(1).toInt();
qDebug() << i << ":" << args.at(i) << rxArgPid.cap(1) << pid;
}
else if (rxArgFooEna.indexIn(args.at(i)) != -1 ) {
qDebug() << i << ":" << args.at(i) << "Enable Foo";
}
else if (rxArgFooDis.indexIn(args.at(i)) != -1 ) {
qDebug() << i << ":" << args.at(i) << "Disable Foo";
}
else {
qDebug() << "Uknown arg:" << args.at(i);
}
}
return 0;
}
Существует также QxtCommandOptions от http://www.libqxt.org/
Этот пакет поддерживает --disable-foo и --enable-foo через opts.addSwitch( "disable-foo", & foo_disabled); и opts.addSwitch( "enable-foo", & foo_enabled);. Вам нужно обработать проверку обоих, и иметь дело с кем-то, определяющим оба (oops).
Я не понимаю, как это имеет отношение к QT4...
На самом деле простой метод - сканирование аргументов "key = value",
поместите их в таблицу, скажем zz.map: QString → QVariant,
и получить их значения с помощью zz.map.value(ключ, по умолчанию).
Пример:
#include "ztest.h"
Ztest zz;
int main( int argc, char* argv[] )
{
zz.eqargs( ++ argv ); // scan test=2 x=str ... to zz.map
QString xx = zz.map.value( "xx", "" );
if( Zint( Size, 10 )) // a #def -> zz.map.value( "Size", 10 )
...
ztest.h
1 страница, ниже; то же самое для Python ~ 10 строк.
(У всех есть свой любимый парсер параметров;
это о простейшем.
Стоит повторять: однако вы указываете параметры, эхо их выводите файлы -
"У каждого ученого, которого я знаю, есть проблемы с отслеживанием
из каких параметров они использовали последний раз, когда они запускали script ".)
Для работы QPoints и т.д., конечно, необходим QSString → QPoint-парсер. Кто-нибудь знает, почему это не работает (в Qt 4.4.3)?
QPoint pt(0,0);
QDataStream s( "QPoint(1,2)" );
s >> pt;
qDebug() << "pt:" << pt; // QPoint(1364225897,1853106225) ??
Добавлено 25nov -
// ztest.h: scan args x=2 s=str ... to a key -> string table
// usage:
// Ztest ztest;
// int main( int argc, char* argv[] )
// {
// QApplication app( argc, argv );
// ztest.eqargs( ++ argv ); // scan leading args name=value ...
// int x = Zint( x, 10 ); // arg x= or default 10
// qreal ff = Zreal( ff, 3.14 );
// QString s = Zstr( s, "default" );
// care: int misspelled = Zint( misspellled ) -- you lose
//version: 2009-06-09 jun denis
#ifndef ztest_h
#define ztest_h
#include <QHash>
#include <QString>
#include <QVariant>
#include <QRegExp>
//------------------------------------------------------------------------------
class Ztest {
public:
QHash< QString, QVariant > map;
int test; // arg test=num, if( ztest.test )
Ztest() : test( 0 ) {}
QVariant val( const QString& key, const QVariant& default_ = 0 )
{
return map.value( key, default_ );
}
void setval( const QString& key, const QVariant& val )
{
map[key] = val;
if( key == "test" || key == "Test" )
test = val.toInt();
}
//------------------------------------------------------------------------------
// ztest.eqargs( ++ argv ) scans test=2 x=3 ... -> ztest table
void eqargs( char** argv )
{
char** argv0 = argv;
char *arg;
QRegExp re( "(\\w+)=(.*)" ); // name= anything, but not ./file=name
for( ; (arg = *argv) && re.exactMatch( arg ); argv ++ ){
setval( re.cap(1), re.cap(2) );
}
// change argv[0..] -> args after all name=values
while(( *argv0++ = *argv++) != 0 ) {}
}
};
extern Ztest ztest;
// macros: int x = Zint( x, 10 ): x= arg or default 10
#define Zstr( key, default ) ztest.val( #key, default ).toString()
#define Zint( key, default ) ztest.val( #key, default ).toInt()
#define Zreal( key, default ) ztest.val( #key, default ).toDouble()
#endif
Посмотрите на это: http://code.google.com/p/qtargparser/
В 2013 году и до сих пор нет парсера "1-го участника". В любом случае.. если кто-то окажется перед той же проблемой и хотел бы избежать кривых обучения, которые поставляются с libs-компиляторами cmd, вот вам "быстрое и грязное" решение: -
QString QArgByKey(QString key, QChar sep = QChar('\0') ) //prototype usually in separate header
QString QArgByKey(QString key, QChar sep )
{
bool sepd=sep!=QChar('\0');
int pos=sepd?qApp->arguments().indexOf(QRegExp('^'+key+sep+"\\S*")):qApp->arguments().indexOf(QRegExp(key));
return pos==-1?QString::null:
(sepd?qApp->arguments().at(pos).split(sep).at(1):(++pos<qApp->arguments().size()?qApp->arguments().at(pos):QString::null));
}
Пример: -
[email protected]:~$ ./myApp firstKey=Value1 --secondKey Value2 thirdKey=val3.1,val3.2,val3.3 --enable-foo
Использование:
QString param1 = QArgByKey("firstkey",'='); // Returns `Value1` from first pair
QString param2 = QArgByKey("--secondkey"); // Returns `Value2` from second pair
QString param3-1 = QArgByKey("thirdkey",'=').split(',').at(0); // Returns `val3.1`
bool fooEnabled = qApp->arguments().contains("--enable-foo"); //To check for `--enable-foo`
Парамы могут передаваться в любом порядке
Изменить: Обновления этого фрагмента будут найдены здесь
Должен ли он быть Qt4 конкретным? Если нет, GNU Getopt действительно приятно, хотя лицензирование может быть проблемой, если вы не используете программное обеспечение с открытым исходным кодом.
Также для синтаксического анализа некоторых опций вы можете попробовать gperf.
В IBM есть хороший учебник.
Еще один вариант, с которым я столкнулся, тоже смотря, чтобы сделать это:
http://code.google.com/p/qgetopts/
Я не использовал его, хотя.