嵌入式双引号在QT 4.7.4中工作,而不是在4.8.6中

时间:2015-04-20 19:18:32

标签: c++ qt

我有一个Qt 4.7.4应用程序正在运行。我正在尝试更新到Qt 4.8.6,但版本4.8.6没有处理嵌入式双引号,如4.7.4。

作为示例,以下字符串是我们用作QApplication参数的十二个字符串之一:

QString myData = 
    QString("{\"type\":\"IndexFlt\",\"media\":\"1\",\"entityid\":\"0:0:0\"}");

在4.7.4版本中,12个字符串作为argv的一部分传递给QApplication。

当我在版本4.7.4中通过theApp.arguments()获取参数时,我得到了所有参数,格式没有变化。

然而,当我将相同的argumetns传递给版本4.8.6然后调用theApp.arguments()时,QStringList只有六个条目而不是十二个。

当我看到第6个字符串时,我看到QT接受了7-12个参数并将它们添加到前六个。

我在调试器中看到的参数的QStringList在4.7.4和4.8.6之间是不同的。在4.7.4

我认为参数6为:

"{"type":"IndexFlt","media":"1","entityid":"0:0:0"}"

但是对于版本4.8.6,我将参数6视为:

"{\type":"IndexFlt","media":"1","entityid":"0:0:0"} --ScriptArg:...

正如你所看到的那样,而不是字符串type前面的双引号我得到/而结束}在得到参数后没有得到" 7-12添加到参数6.

有关如何解决此问题的任何想法?在应用程序中唯一改变的是Qt的版本。

您可以使用以下代码查看嵌入双引号的问题。 只需确保在第一个参数中至少使用两个参数 包含嵌入的双引号。所以如果下面的代码是一个例子 编译成一个名为test.exe的exe然后你会以这种方式调用test.exe: test.exe - DoubleQuotes =" true" -NoDoubleQuotes =假

#include <QtGui/QApplication>
#include <QtCore/QStringList>
#include <iostream>

int main(int argc, char** argv)
{

    for (int i=0; i < argc ; i++)
    {
        std::string tmp = argv[i];
        std::cout << tmp << std::endl;
    }

    QApplication theApp(argc, argv);

    QStringList vArgs = theApp.arguments();
    foreach (QString t, vArgs)
    {
        std::cout << t.toStdString() << std::endl;
    }
}

1 个答案:

答案 0 :(得分:1)

您遇到的问题源于argv解析Qt 4.8.6模板函数qWinCmdLine<>()(来自qcorecmdlineargs_p.h)中的错误。

在Qt 4.7.4中,该函数中处理命令行上的转义引号的代码部分看起来像(左栏中的注释是我的注释):

                    if (*p == '\\') {                // escape char?
/* skip escape */       p++;
                        if (*p == Char('\"') || *p == Char('\''))
/* keep quote */            ;                        // yes
                        else
/* else undo */             p--;                        // treat \ literally
                    } else {
                        if (!quote && (*p == Char('\"') || *p == Char('\''))) {        // " or ' quote
/* note and */              quote = *p++;               
/* skip quote */            continue;
                        } else if (QChar((short)(*p)).isSpace() && !quote)
                            break;
                    }

在Qt 4.8.6中,该部分功能如下:

                    if (*p == '\\') {                // escape char?
/* BUG */               if (*(p+1) == quote)
                            p++;
                    } else {
                        if (!quote && (*p == Char('\"') || *p == Char('\''))) {        // " or ' quote
                            quote = *p++;
                            continue;
                        } else if (QChar((short)(*p)).isSpace() && !quote)
                            break;

这些片段非常相似,只是如果4.8.6代码看到下一个字符是quote而不是4.7.4,则跳过转义字符会试图更加聪明一点。跳过转义字符然后撤消该操作的技术,如果它注意到下一个字符不是'\"''\'。问题是,在我注释为/* BUG */的行中,仅当您已经在引用的部分中时才设置变量quote。它没有正确处理在命令行的引用部分中没有的转义引号字符。

请注意,在Qt 4.8.6和Qt 5.3.1之间的某个时间,qWinCmdLine<>()函数不再用于桌面Windows目标(它仅用于WinCE目标)。相反,Win32 API CommandLineToArgvW()用于将命令行解析为argv数组 - 看起来它会带回您正在寻找的行为(看起来该错误已在WinCE中修复 - 只有qWinCmdLine<>()的版本。

因此,为了解决您的问题,您需要使用除4.8.6之外的Qt版本(我不确定错误在哪个版本中悄悄进入,或者确切地说在修复时),或者您如果由于某种原因需要4.8.6,可以修补qcorecmdlineargs_p.h文件并重建Qt。

另请注意,在Windows上,QCoreApplication(因此QApplication)会忽略您传入的argcargv参数。始终获取已解析的命令行来自Win32 API GetCommandLine()。虽然记录了这种行为,但是当我尝试通过将不同的argc / argv值传递给QCoreApplication来测试时,它并不是我所期望的并且有点令人恼火。效果。