嵌入的双引号适用于QT 4.7.4,而不适用于4.8.6
Embedded double quotes work in QT 4.7.4 not in 4.8.6
我有一个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
)会忽略传入的argc
和argv
参数。解析的命令行始终从Win32 APIGetCommandLine()
获取。虽然这种行为已经记录在案,但这并不是我所期望的,当我试图通过将不同的argc
/argv
值传递给QCoreApplication
来测试时,这有点令人恼火,但没有任何效果。
- OpenGL - 在 NDC 中计算位置适用于着色器,但不适用于'regular'程序
- 使用模板参数重载C++方法:如何使其适用于模板的子类?
- 如何修复我的最大公约数代码?它适用于除零和零以外的所有数字
- 选择排序C++(已修改)并非适用于所有情况
- 无法让"std::enable_if"适用于无作用域枚举
- 请找出我的代码中的错误,它在提交得到错误答案的同时仍然适用于我的所有测试用例
- 确定夏令时是否适用于特定日期
- 是否有一种 STL 算法可以最后找到,但它也适用于指针?
- 十进制到二进制的实现不能完全适用于我大学的检查器。问题或提示可能是什么
- 使用程序集嵌入数据时"Undefined reference"错误,使用适用于窗口的 mingw-w64 编译(COFF 而不是 ELF)
- 为什么 std::vector 适用于类定义中的不完整类型?
- 为什么哈希<常量字符*>适用于字符串而不是字符串变量?
- Lambda适用于最新的Visual Studio,但在其他地方不起作用
- 我该如何文档文档以使文档适用于类成员而不是匿名类型
- 计算 c# 中二进制文件符号的频率不起作用,但适用于等效的 c++ 代码
- 为什么 fstream.open(文件名) 适用于文字而不是生成的字符串?
- 模板重载和 SFINAE 仅适用于函数而不是类
- 为什么链接器不抱怨多个函数定义(仅适用于模板化函数)
- 我可以使用' == '来比较两个向量吗?我试过了,似乎工作正常。但我不知道它是否适用于更复杂的情况
- 延长临时的生命周期,适用于块范围的聚合,但不是通过"新";为什么?