嵌入的双引号适用于QT 4.7.4,而不适用于4.8.6

Embedded double quotes work in QT 4.7.4 not in 4.8.6

本文关键字:适用于 不适用 QT      更新时间:2023-10-16

我有一个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中,作为argv的一部分传递给QApplication的十二个字符串。

当我在版本4.7.4中通过theApp.arguments()返回参数时,我会在格式不变的情况下返回所有参数。

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

当我看第六个字符串时,我发现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,然后您可以通过这种方式envoke test.exe:test.exe--DoubleQuotes="true"-NoDoubleQuotes=false

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

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

在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;
}

在问题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 APICommandLineToArgvW()用于将命令行解析为argv数组-看起来这会返回您要查找的行为(看起来该错误在qWinCmdLine<>()的WinCE纯版本中也已修复)。

因此,要解决您的问题,您需要使用除4.8.6之外的Qt版本(我不确定错误是在哪个版本出现的,也不确定它是何时修复的),或者,如果出于某种原因需要4.8.6,您可以修补qcorecmdlineargs_p.h文件并重建Qt。

还要注意,在Windows上,QCoreApplication(因此QApplication)会忽略传入的argcargv参数。解析的命令行始终从Win32 APIGetCommandLine()获取。虽然这种行为已经记录在案,但这并不是我所期望的,当我试图通过将不同的argc/argv值传递给QCoreApplication来测试时,这有点令人恼火,但没有任何效果。

相关文章: