0

Windows 中的 QCommandLineParser 和文件名通配符有问题吗?

我在 Windows 上使用 Qt 5.8.0 开源来构建控制台应用程序。我正在尝试构建一个接受文件名通配符的命令行实用程序。这似乎不起作用,因为它依赖于 process() 方法。

主.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

当我使用命令时:

myapp somefile.txt

我明白了somefile.txt

但这不适用于以下命令:

myapp *.txt

解决这个问题的最佳方法是什么?

4

2 回答 2

2

QCommandLineParser只存储和检索命令行参数。它对文件系统一无所知;如果要扩展通配符,则需要自己获取QDir并设置其名称过滤器,如下所示:

#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';
       }
   }
}

当然,您需要更聪明一点才能接受任意路径通配符 - 在这里,我们假设参数中没有路径分隔符。

于 2018-11-20T17:45:47.693 回答
0

在此问题得到解决之前,我的解决方案是确保将带有通配符的参数用单引号括起来。然后以类似于Toby Speight建议的方式解析通配符:

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;
}
于 2018-11-20T20:38:41.100 回答