【原创&交流】qt解释json字符串的一个bug

clever101
博客专家认证
2017-11-11 06:32:27
链接:qt解释json字符串的一个bug

最近使用qt(我用的是qt5.6)解析json字符串,发现qt的一个bug,代码如下:

#include <QtCore/QCoreApplication>
#include <QDomComment>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonArray>
#include <iostream>
#include<iomanip>
#include "json.h"

#if defined(_MSC_VER) && (_MSC_VER >= 1600)
# pragma execution_character_set("utf-8")
#endif

int QtJsonTest()
{
QJsonParseError jsonError;
QString qstrJson = "{\n \"result\": true,\n \"error\": \"\",\n \"data\": {\n \"User\": {\n \"Uid\": 20556426650023957,\n \"Username\": \"00B10C201D61\",\n \"Password\": \"e10adc3949ba59abbe56e057f20f883e\",\n \"Appid\": 9,\n \"Sex\": \"\",\n \"Email\": \"\",\n \"GroupId\": 0,\n \"ParentId\": 0,\n \"Status\": \"\",\n \"Registertime\": \"2017-11-10T10:35:38+08:00\",\n \"Nikename\": \"\",\n \"TelNumber\": \"\",\n \"Lastlogintime\": \"2017-11-10T19:37:28.305962078+08:00\",\n \"Role\": \"\",\n \"Address\": \"\",\n \"IconPath\": \"\",\n \"ImagePath\": \"\",\n \"Type\": 0,\n \"Admin\": false,\n \"Option\": \"\",\n \"Terminals\": null\n },\n \"sessionid\": \"62719fc6cd0fc53a5dad5fed77ebfbd3\",\n \"pushsessionid\": \"9_20556426650023957_4de289715bed48e21c919b48febd7ae2\"\n }\n}";
QJsonDocument json = QJsonDocument::fromJson(qstrJson.toUtf8(), &jsonError);
if (jsonError.error == QJsonParseError::NoError)
{
if (json.isObject())
{
QJsonObject rootObj = json.object();

if (rootObj.contains("data"))
{
QJsonValue data_value = rootObj.value(QString("data"));

QJsonObject contentObj = data_value.toObject();

if (contentObj.contains("User"))
{
QJsonValue user_value = contentObj.value(QString("User"));

QJsonObject userObj = user_value.toObject();

if (userObj.contains("Uid"))
{
QJsonValue UidValue = userObj.value("Uid");

QJsonValue::Type type = UidValue.type();
if (UidValue.isDouble())
{
double db = UidValue.toDouble();
QString info("QT解析json字符串结果:");
std::wcout << info.toStdWString()<< std::fixed << db << std::endl;

return 0;
}

}
}
}
}
}
return 1;
}

int JsoncppTest()
{
QString qstrJson = "{\n \"result\": true,\n \"error\": \"\",\n \"data\": {\n \"User\": {\n \"Uid\": 20556426650023957,\n \"Username\": \"00B10C201D61\",\n \"Password\": \"e10adc3949ba59abbe56e057f20f883e\",\n \"Appid\": 9,\n \"Sex\": \"\",\n \"Email\": \"\",\n \"GroupId\": 0,\n \"ParentId\": 0,\n \"Status\": \"\",\n \"Registertime\": \"2017-11-10T10:35:38+08:00\",\n \"Nikename\": \"\",\n \"TelNumber\": \"\",\n \"Lastlogintime\": \"2017-11-10T19:37:28.305962078+08:00\",\n \"Role\": \"\",\n \"Address\": \"\",\n \"IconPath\": \"\",\n \"ImagePath\": \"\",\n \"Type\": 0,\n \"Admin\": false,\n \"Option\": \"\",\n \"Terminals\": null\n },\n \"sessionid\": \"62719fc6cd0fc53a5dad5fed77ebfbd3\",\n \"pushsessionid\": \"9_20556426650023957_4de289715bed48e21c919b48febd7ae2\"\n }\n}";

Json::Reader reader;
Json::Value root;
if (reader.parse(qstrJson.toStdString(), root)) // reader将Json字符串解析到root,root将包含Json里所有子元素
{
qint64 uid = root["data"]["User"]["Uid"].asInt64(); // 访问节点
QString info("Jsoncpp库解析json字符串结果:");
std::wcout << info.toStdWString() << uid << std::endl;
return 0;
}
else
{
return 1;
}
return 1;
}

int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
//先注册自己的MsgHandler

setlocale(LC_CTYPE, "chs");

QtJsonTest();

JsoncppTest();

getchar();
return 1;
}


代码编译环境为VS2013,Win7操作系统,unicode字符集,输出结果如下:

从上图可以看出jsoncpp的解析精度比qt5要高。通过查看qt源码也可以看出,qt对json类型的支持比较有限,仅支持以下类型:

enum Type {
Null = 0x0,
Bool = 0x1,
Double = 0x2,
String = 0x3,
Array = 0x4,
Object = 0x5,
Undefined = 0x80
};


jsoncpp支持json的类型比qt要多,具体是:

enum ValueType {
nullValue = 0, ///< 'null' value
intValue, ///< signed integer value
uintValue, ///< unsigned integer value
realValue, ///< double value
stringValue, ///< UTF-8 string value
booleanValue, ///< bool value
arrayValue, ///< array value (ordered list)
objectValue ///< object value (collection of name/value pairs).
};
...全文
300 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
clever101 2017-11-17
  • 打赏
  • 举报
回复
引用 7 楼 xh286286 的回复:
[quote=引用 6 楼 clever101 的回复:] [quote=引用 5 楼 dext 的回复:] 答案是 Yes and No Yes Qt 的确没有精确的读到你想读到的数据。 No,JSON 源自 JavaScript 在 js 中,没有 整数和浮点数,只有Number,而根据现行的js标准,整数是 32位,浮点数是 64位。所以 Qt只是实现了标准,其他的库可能有扩充,单已经不是标准的JSON,。一个ID几乎不会参与数学运算,所以设计成 数字 本身就是 JSON DATA的设计问题。 JSON DATA TYPE JS NUMBER
多谢大侠指教,我还有一事不明,按你的意思qt已经按照json的标准实现,根据现行的js标准,整数是 32位,浮点数是 64位,那么请看看qt定义的类型,如下:

    enum Type {
        Null =  0x0,
        Bool = 0x1,
        Double = 0x2,
        String = 0x3,
        Array = 0x4,
        Object = 0x5,
        Undefined = 0x80
    };
请问哪一种类型对应int32呢?[/quote] double啊, qt 的int 就是用double 存的。[/quote] 为啥这样设计呢?不能在解析json的枚举里增加一种int32吗?
xh286286 2017-11-16
  • 打赏
  • 举报
回复
引用 6 楼 clever101 的回复:
[quote=引用 5 楼 dext 的回复:] 答案是 Yes and No Yes Qt 的确没有精确的读到你想读到的数据。 No,JSON 源自 JavaScript 在 js 中,没有 整数和浮点数,只有Number,而根据现行的js标准,整数是 32位,浮点数是 64位。所以 Qt只是实现了标准,其他的库可能有扩充,单已经不是标准的JSON,。一个ID几乎不会参与数学运算,所以设计成 数字 本身就是 JSON DATA的设计问题。 JSON DATA TYPE JS NUMBER
多谢大侠指教,我还有一事不明,按你的意思qt已经按照json的标准实现,根据现行的js标准,整数是 32位,浮点数是 64位,那么请看看qt定义的类型,如下:

    enum Type {
        Null =  0x0,
        Bool = 0x1,
        Double = 0x2,
        String = 0x3,
        Array = 0x4,
        Object = 0x5,
        Undefined = 0x80
    };
请问哪一种类型对应int32呢?[/quote] double啊, qt 的int 就是用double 存的。
clever101 2017-11-16
  • 打赏
  • 举报
回复
引用 5 楼 dext 的回复:
答案是 Yes and No Yes Qt 的确没有精确的读到你想读到的数据。 No,JSON 源自 JavaScript 在 js 中,没有 整数和浮点数,只有Number,而根据现行的js标准,整数是 32位,浮点数是 64位。所以 Qt只是实现了标准,其他的库可能有扩充,单已经不是标准的JSON,。一个ID几乎不会参与数学运算,所以设计成 数字 本身就是 JSON DATA的设计问题。 JSON DATA TYPE JS NUMBER
多谢大侠指教,我还有一事不明,按你的意思qt已经按照json的标准实现,根据现行的js标准,整数是 32位,浮点数是 64位,那么请看看qt定义的类型,如下:

    enum Type {
        Null =  0x0,
        Bool = 0x1,
        Double = 0x2,
        String = 0x3,
        Array = 0x4,
        Object = 0x5,
        Undefined = 0x80
    };
请问哪一种类型对应int32呢?
clever101 2017-11-13
  • 打赏
  • 举报
回复
引用 2 楼 u010370871 的回复:
一个用qint64,一个用double。。。。。。 再说了你把Qt的枚举再拆成c++原生的看看一样么?
qt的json解释不支持int64类型本身就有问题,还有如何把Qt的枚举再拆成c++原生的呢?
张小飞Official 2017-11-13
  • 打赏
  • 举报
回复
一个用qint64,一个用double。。。。。。 再说了你把Qt的枚举再拆成c++原生的看看一样么?
dext 2017-11-13
  • 打赏
  • 举报
回复
答案是 Yes and No Yes Qt 的确没有精确的读到你想读到的数据。 No,JSON 源自 JavaScript 在 js 中,没有 整数和浮点数,只有Number,而根据现行的js标准,整数是 32位,浮点数是 64位。所以 Qt只是实现了标准,其他的库可能有扩充,单已经不是标准的JSON,。一个ID几乎不会参与数学运算,所以设计成 数字 本身就是 JSON DATA的设计问题。 JSON DATA TYPE JS NUMBER
FoolCarpe 2017-11-13
  • 打赏
  • 举报
回复
谢谢分享。 jsoncpp或者rapidjson 都还不错!
张小飞Official 2017-11-13
  • 打赏
  • 举报
回复
引用 3 楼 clever101 的回复:
[quote=引用 2 楼 u010370871 的回复:] 一个用qint64,一个用double。。。。。。 再说了你把Qt的枚举再拆成c++原生的看看一样么?
qt的json解释不支持int64类型本身就有问题,还有如何把Qt的枚举再拆成c++原生的呢?[/quote] 直接看源码不就可以了么???

16,215

社区成员

发帖
与我相关
我的任务
社区描述
Qt 是一个跨平台应用程序框架。通过使用 Qt,您可以一次性开发应用程序和用户界面,然后将其部署到多个桌面和嵌入式操作系统,而无需重复编写源代码。
社区管理员
  • Qt
  • 亭台六七座
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧