我有一个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;
}
}
答案 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
)会忽略您传入的argc
和argv
参数。始终获取已解析的命令行来自Win32 API GetCommandLine()
。虽然记录了这种行为,但是当我尝试通过将不同的argc
/ argv
值传递给QCoreApplication
来测试时,它并不是我所期望的并且有点令人恼火。效果。