QT中的JSON存储时无序问题的思考与解决

项目场景:

最近在写一款通用的CAN设备上位机,需要用到JSON来存储文件,至于为什么用JSON?因为简单,性能不作要求,刚好之前也了解过JSON,所以就开干了,之前也考虑过xml,感觉不那么简单易懂,就放弃了。


问题描述

在保存数据项的时候,发现我之前按顺序保存的数据,再次读取出来时,竟然有些不同。我原来的顺序是“1”,“2”,... ,"11"。但是到了"1",下一个却不是"2",而是"10",呃,这是给我按字母升序了。

 去看了一下QT 的JSON头文件,果然,这家伙底层是用map实现的:

QT_BEGIN_NAMESPACE
class QDebug;
template <class Key, class T> class QMap;
typedef QMap<QString, QVariant> QVariantMap;
template <class Key, class T> class QHash;
typedef QHash<QString, QVariant> QVariantHash;

在C++容器里面,map是属于无序的容器,会自动升序或者降序。呃,这就很痛苦了,,思索万千,掉了不少头发,因为QT的QJsonObject还没有关掉自动排序这个开关。。


解决方案:

想来想去,还是既然改变不了被BUG强J的事实,不如坦然接受。既然他是按字母升序的,那就找出规则来。这个时候就上表格了

发现它是以前面的字母一一做比较的,如果第一位顺序相同,则比较第二位,如此类推。如果第一位对比的顺序不同,则不管后面的位数了 。如"10"与"2",先比较"1"与"2",发现"1"在"2"前面,就不管后面的"0"了,"10"就是排在"2"前面。

怎么办呢。那么就让第一位相同,后面的按顺序排序即可。使用表格验证,可以看到,无论是升序和降序,都是有序的的。

 那么在代码中怎么使用呢?

简单,新建一个数组,把这个值存进去,用的时候,变成字符串即可。

 

//我这里搞了一万个,因为我存储的个数不过超过这么多
for (int i = 10000; i < 20000; ++i)
		fIndex[i - 10000] = i;

/*******************
 ......一些代码
********************/

for (int k = 0; k < pGboleData.at(i).cItem.at(j).pItem.size(); k++)
{
				 QJsonArray pItem;
				/*******************
                     ......一些代码
                 ********************/

				for(int v=0;v< sspro.size();v++)
				{
					QJsonArray itemarr;
					/*******************
                     ......一些代码
                    ********************/
					//这里的key用我们生成的来代替数组
					cellPr.insert(QString::number(fIndex[v]), itemarr);
					//ibegin++;
				}
				
				pItem.append(cellPr);
                //这里的key用我们生成的来代替数组
				pDItem.insert(QString::number(fIndex[k]), pItem);
}

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
QT解析JSON数据出现乱码,可能是因为编码不一致导致的。可以尝试以下方法解决: 1. 手动设置JSON数据的编码格式,比如: ```cpp QByteArray jsonData = ...; // 从网络或文件读取JSON数据 QTextCodec *codec = QTextCodec::codecForName("UTF-8"); // 设置编码方式为UTF-8 QString jsonString = codec->toUnicode(jsonData); // 将JSON数据转为QString类型 QJsonDocument jsonDoc = QJsonDocument::fromJson(jsonString.toUtf8()); // 解析JSON数据 ``` 2. 在QT使用QJsonDocument解析JSON数据,可以指定文本编码方式,比如: ```cpp QByteArray jsonData = ...; // 从网络或文件读取JSON数据 QJsonParseError error; QJsonDocument jsonDoc = QJsonDocument::fromJson(jsonData, &error); if (error.error == QJsonParseError::NoError) { // 解析成功 } else { // 解析失败 qDebug() << "Parse JSON error:" << error.errorString(); } ``` 其,`QJsonDocument::fromJson`函数的第二个参数默认为`QJsonDocument::JsonFormat::Compact`,表示紧凑格式,如果JSON数据包含非ASCII字符,可能会出现乱码。可以改为使用`QJsonDocument::JsonFormat::Indented`格式,这样就能正确解析包含非ASCII字符的JSON数据。 ```cpp QByteArray jsonData = ...; // 从网络或文件读取JSON数据 QJsonParseError error; QJsonDocument jsonDoc = QJsonDocument::fromJson(jsonData, &error, QJsonDocument::Indented); if (error.error == QJsonParseError::NoError) { // 解析成功 } else { // 解析失败 qDebug() << "Parse JSON error:" << error.errorString(); } ``` 3. 如果JSON数据文件使用的是其他编码格式(比如GBK),可以先将其转为UTF-8格式再解析。可以使用`QTextCodec`类来实现转换,比如: ```cpp QFile file("data.json"); if (file.open(QIODevice::ReadOnly | QIODevice::Text)) { QByteArray jsonData = file.readAll(); QTextCodec *codec = QTextCodec::codecForName("GBK"); QString jsonString = codec->toUnicode(jsonData); // 将GBK编码的数据转为QString类型 QJsonDocument jsonDoc = QJsonDocument::fromJson(jsonString.toUtf8()); // 解析JSON数据 file.close(); } ``` 以上是一些常见的解决乱码的方法,希望能够帮到你。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值