JimmyG
JimmyG

Reputation: 131

How to use filename wildcards with QCommandLineParser

Is there a problem with QCommandLineParser and filename wildcards in Windows?

I'm using Qt 5.8.0 opensource on Windows to build a console application. I'm trying to build a command line utility that accepts filename wildcards. This doesn't seem to work, as it bails on the process() method.

main.cpp:

#include <QCoreApplication>
#include <QCommandLineParser>
#include <iostream>
#include <cstdlib>

using namespace std;

int main(int argc, char** argv)
{
   QCoreApplication app(argc, argv);
   QCommandLineParser parser;
   parser.addPositionalArgument("files", "input files", "[file]...");
   parser.process(app);
   QStringList posargs = parser.positionalArguments();
   foreach(QString s, posargs)
      cout << s.toStdString() << endl;
   return EXIT_SUCCESS;
}

myapp.pro

CONFIG += c++14 console release
QT -= gui
sources = main.cpp

When I use the command:

myapp somefile.txt

I get somefile.txt

But this does not work with the command:

myapp *.txt

What's the best way around this?

Upvotes: 0

Views: 422

Answers (2)

JimmyG
JimmyG

Reputation: 131

Until this gets fixed, my solution is to make sure to enclose parameters with wildcards in them with single quotes. Then parse out the wildcard in a manner similar to what Toby Speight suggested:

int main(int argc, char** argv)
{
   QCoreApplication app(argc, argv);
   QCommandLineParser parser;
   parser.addPositionalArgument("files", "input files", "[file]...");
   parser.process(app);
   QStringList posargs = parser.positionalArguments();
   for(auto s: posargs)
   {
      if(s.startsWith("'") && s.endsWith("'"))
         s = s.mid(1,s.length()-2);
      QFileInfo fi(s);
      QDirIterator iter(fi.path(), QStringList() << fi.fileName(), QDir::Files);
      while(iter.hasNext())
      {
         QString filename = iter.next();
         cout << s.toStdString() << endl;
      }
   }
   return EXIT_SUCCESS;
}

Upvotes: 0

Toby Speight
Toby Speight

Reputation: 30878

QCommandLineParser just stores and retrieves the command-line arguments. It knows nothing about filesystem; if you want to expand a wildcard, you'll need to take a QDir and set its name filter yourself, like this:

#include <QCoreApplication>
#include <QCommandLineParser>
#include <QDir>

#include <iostream>

int main(int argc, char** argv)
{
   QCoreApplication app(argc, argv);
   QCommandLineParser parser;
   parser.addPositionalArgument("files", "input files", "[file]...");
   parser.process(app);
   QStringList posargs = parser.positionalArguments();
   for (auto const& s: posargs) {
       auto d = QDir{};
       d.setNameFilters({s});
       for (const auto& name: d.entryList()) {
           std::cout << name.toStdString() << '\n';
       }
   }
}

You'll need to be a bit cleverer to accept arbitrary path wildcards, of course - here, we assume there's no path separator within the argument.

Upvotes: 2

Related Questions