parse command line options outside of main()?



  • Hi All,
    I am writing a program that does command line parsing. For now the lines that deal with this are in main.cpp, in the constructor. I would like to move this to it's own function, so re-using should be easier, and the function will have less lines. I encounter the following obstacles in my attempt:
    ->QCommandLineParser requires access to argc and *argv[], so I have to pass those to my function. This is not a big problem, I can just give them as arguments.
    ->QCommandLineParser requires access to the QCoreApplication instance. In a new empty Qt console application, this is a local variable. I think it's not a good idea to define this variable outside the main constructor.
    Is there a solution to break up the main function into smaller functions?
    My versions:
    Windows 7 enterprise SP1 64 bit
    Qt Creator 3.6.0 Based on Qt 5.5.1 (MSVC 2013, 32 bit)
    QT5.5, mingw492_32
    Cheers,
    Cedric


  • Qt Champions 2016

    Hello,

    ->QCommandLineParser requires access to argc and *argv[], so I have to pass those to my function. This is not a big problem, I can just give them as arguments.
    ->QCommandLineParser requires access to the QCoreApplication instance. In a new empty Qt console application, this is a local variable. I think it's not a good idea to define

    It requires neither of those. It requires a list of strings (QStringList) containing the command line (application path + arguments).

    outside the main constructor.

    The main constructor?



  • Hi kshegunov,
    Thanks for your quick reply. I have made a minimal program that works:

    #include <QCoreApplication>
    #include <QCommandLineParser>
    #include <QDebug>
    
    int main(int argc, char *argv[])
    {
        QCoreApplication a(argc, argv);
        QCommandLineParser parser;
        parser.setApplicationDescription("Explaining text");
        parser.addHelpOption();
    
        //An option with a value
        QCommandLineOption targetDirectoryOption(QStringList() << "t" << "target-directory",
                QCoreApplication::translate("main", "Copy all source files into <directory>."),
                QCoreApplication::translate("main", "directory"));
        parser.addOption(targetDirectoryOption);
        // Process the actual command line arguments given by the user
        parser.process(a);
    
        QString target = parser.value(targetDirectoryOption);
        qDebug()<<target;
    
        return a.exec();
    }
    

    This version gives the following error when I uncomment
    parser.process(a);
    error: 'a' was not declared in this scope
    Without this line, I get the following run-time errors:
    QCommandLineParser: call process() or parse() before value
    QCommandLineParser: call process() or parse() before values

    #include <QCoreApplication>
    #include <QCommandLineParser>
    #include <QDebug>
    
    void parseCommandLine();
    
    int main(int argc, char *argv[])
    {
        QCoreApplication a(argc, argv);
        parseCommandLine();
        return a.exec();
    }
    
    void parseCommandLine()
    {
        QCommandLineParser parser;
        parser.setApplicationDescription("Explaining text");
        parser.addHelpOption();
    
        //An option with a value
        QCommandLineOption targetDirectoryOption(QStringList() << "t" << "target-directory",
                QCoreApplication::translate("main", "Copy all source files into <directory>."),
                QCoreApplication::translate("main", "directory"));
        parser.addOption(targetDirectoryOption);
        // Process the actual command line arguments given by the user
        //parser.process(a); //error: 'a' was not declared in this scope
    
        QString target = parser.value(targetDirectoryOption);
        qDebug()<<target;
    }
    

    I see the following page has an example, that passes a reference to the parser object.
    http://doc.qt.io/qt-5/qcommandlineparser.html
    I will try that and report back.
    Cheers,
    Cedric



  • Hi All,
    The following works, so my problem is fixed:

    #include <QCoreApplication>
    #include <QCommandLineParser>
    #include <QDebug>
    
    void parseCommandLine(QCommandLineParser &parser);
    
    int main(int argc, char *argv[])
    {
        QCoreApplication a(argc, argv);
        QCommandLineParser parser;
        parseCommandLine(parser);
        return a.exec();
    }
    
    void parseCommandLine(QCommandLineParser &parser)
    {
    
        parser.setApplicationDescription("Explaining text");
        parser.addHelpOption();
    
        //An option with a value
        QCommandLineOption targetDirectoryOption(QStringList() << "t" << "target-directory",
                QCoreApplication::translate("main", "Copy all source files into <directory>."),
                QCoreApplication::translate("main", "directory"));
        parser.addOption(targetDirectoryOption);
        // Process the actual command line arguments given by the user
        parser.process(QCoreApplication::arguments());
    
        QString target = parser.value(targetDirectoryOption);
        qDebug()<<target;
    }
    

    Cheers,
    Cedric



  • also you can easily get the application instance wherever you want using QCoreApplication::instance() static method


  • Qt Champions 2016

    @cdwijs
    Why not pass the actual arguments instead? E.g:

    #include <QCoreApplication>
    #include <QCommandLineParser>
    #include <QDebug>
    
    void parseCommandLine(const QStringList &);
    
    int main(int argc, char *argv[])
    {
        QCoreApplication a(argc, argv);
    
        parseCommandLine(QCoreApplication::arguments());
    
        return QCoreApplication::exec();
    }
    
    void parseCommandLine(const QStringList & arguments)
    {
        QCommandLineParser parser;
        // ...
        parser.process(arguments); //< I advise QCommandLineParser::parse instead, since it doesn't call exit() on error.
        // ...
    }
    


  • @kshegunov
    QStringList is new for me, that's the reason :-)
    Your solution is clean, as the main function now doesn't have to know anything about parsing.
    Now I can create a class that does nothing more than parsing the strings, and put them into a QSettings object.

    Thanks for your help,
    Cedric


  • Qt Champions 2016

    You're welcome. Happy coding!


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.