• 2877阅读
  • 19回复

大佬来,QString比较尴尬的地方! [复制链接]

上一主题 下一主题
离线liulin188
 

只看楼主 倒序阅读 楼主  发表于: 2020-04-20
发现一个QString比较尴尬的事情:
对于第三方c库中的c函数比如fun(char *p, ...)
如果直接这样去调用
QString s = 来源(是ui->lineEdit->text()或者是其他
fun(s.toutf8().data())或者直接fun(ui->lineEdit->text().toutf8().data())
这样这个参数实际的内容是可能不确定的,计算结果也可能不对。(是可能,有时候是对的,但是错误也很容易复现!)
如果调用之前这样处理
char buffer[大小] = {0}
sprintf(buffer, s.toutf8().data());(总结发现,用字符串相关的函数没问题,sprintf,strcpy,fprintf都很稳定!
fun(buffer)
这样调用就很稳定,没问题!
观点:不是说QString有问题,而是说.data()转换后的char *作为参数直接调用第三方c函数,可能存在不稳定性!



https://wiki.qt.io/Qt_5.12_Release
https://wiki.qt.io/New_Features_in_Qt_5.12
https://wiki.qt.io/Qt_5.12.0_Known_Issues
https://www.qt.io/blog/qt-5.13.2-released
https://www.qt.io/blog/qt-creator-4.10.2-released
https://wiki.qt.io/Qt_5.12_Tools_and_Versions
离线cycloveu

只看该作者 1楼 发表于: 2020-04-20
因为QString内部的字符串没有'\0'
大道至简 悟在天成
离线liulin188

只看该作者 2楼 发表于: 2020-04-20
@cycloveu
应该不是这个原因,因为在.data()已经转换成'\0'结尾的了。
https://wiki.qt.io/Qt_5.12_Release
https://wiki.qt.io/New_Features_in_Qt_5.12
https://wiki.qt.io/Qt_5.12.0_Known_Issues
https://www.qt.io/blog/qt-5.13.2-released
https://www.qt.io/blog/qt-creator-4.10.2-released
https://wiki.qt.io/Qt_5.12_Tools_and_Versions
离线spygg

只看该作者 3楼 发表于: 2020-04-20
可能是作用域的问题,用个qbytearray中转下再传试试呢
签名就是这么浪
离线liulin188

只看该作者 4楼 发表于: 2020-04-20
回 spygg 的帖子
spygg:可能是作用域的问题,用个qbytearray中转下再传试试呢 (2020-04-20 16:17) 

对,很有可能,肯定是哪里有问题,但是不知道是哪里的问题。。。。
试了下用QByteArray中转也不行,也就是通过.data()转成的char*作为参数,有隐患!
https://wiki.qt.io/Qt_5.12_Release
https://wiki.qt.io/New_Features_in_Qt_5.12
https://wiki.qt.io/Qt_5.12.0_Known_Issues
https://www.qt.io/blog/qt-5.13.2-released
https://www.qt.io/blog/qt-creator-4.10.2-released
https://wiki.qt.io/Qt_5.12_Tools_and_Versions
离线liulin188

只看该作者 5楼 发表于: 2020-04-20
  1. QString request = ui->request->toPlainText().trimmed();
  2.         QByteArray requestData = request.toUtf8();
  3.         char *data = requestData.data();
  4.         curl_easy_setopt(curl, CURLOPT_POSTFIELDS, requestData.data());//或者直接data,或者ui->request->toPlainText().trimmed().toUtf8().data()

我还是直接贴代码吧,这是curl库的一个调用,当然其他的c库也会有问题比如aes加密函数,opencv等等。
不管如何转换,只要.data()作为参数传进去,这个内容就是不稳定的。
比如上面我这样写,textedit里一堆文字,服务端可能只收到一个或多个未知字符,也可能收到完整的。
如果通过sprintf处理下,那就稳如狗了,如下!
  1. char curlPostFields[8192] = {0};
  2. snprintf(curlPostFields, sizeof(curlPostFields) - 1, "%s", ui->request->toPlainText().trimmed().toUtf8().data());
  3. curl_easy_setopt(curl, CURLOPT_POSTFIELDS, curlPostFields);





https://wiki.qt.io/Qt_5.12_Release
https://wiki.qt.io/New_Features_in_Qt_5.12
https://wiki.qt.io/Qt_5.12.0_Known_Issues
https://www.qt.io/blog/qt-5.13.2-released
https://www.qt.io/blog/qt-creator-4.10.2-released
https://wiki.qt.io/Qt_5.12_Tools_and_Versions
离线spygg

只看该作者 6楼 发表于: 2020-04-20
试试这个...
QString request = ui->request->toPlainText().trimmed();
const auto& bytes = request .toUtf8();
const     char *data = bytes.data();


签名就是这么浪
离线fsu0413

只看该作者 7楼 发表于: 2020-04-20
Before version 7.17.0, strings were not copied. Instead the user was forced keep them available until libcurl no longer needed them.

坑在curl这边,你看一下curl的版本
离线liulin188

只看该作者 8楼 发表于: 2020-04-20
回 fsu0413 的帖子
fsu0413:Before version 7.17.0, strings were not copied. Instead the user was forced keep them available until libcurl no longer needed them.
坑在curl这边,你看一下curl的版本 (2020-04-20 22:50) 

我的是7.37.0,我现在试试你那个方法。
curl应该没问题,因为同样.data()不稳定的问题,我在一个aes加密函数里也出现了。
https://wiki.qt.io/Qt_5.12_Release
https://wiki.qt.io/New_Features_in_Qt_5.12
https://wiki.qt.io/Qt_5.12.0_Known_Issues
https://www.qt.io/blog/qt-5.13.2-released
https://www.qt.io/blog/qt-creator-4.10.2-released
https://wiki.qt.io/Qt_5.12_Tools_and_Versions
离线liulin188

只看该作者 9楼 发表于: 2020-04-20
回 spygg 的帖子
spygg:试试这个...
QString request = ui->request->toPlainText().trimmed();
const auto& bytes = request .toUtf8();
const     char *data = bytes.data();
....... (2020-04-20 22:39) 

不行啊
https://wiki.qt.io/Qt_5.12_Release
https://wiki.qt.io/New_Features_in_Qt_5.12
https://wiki.qt.io/Qt_5.12.0_Known_Issues
https://www.qt.io/blog/qt-5.13.2-released
https://www.qt.io/blog/qt-creator-4.10.2-released
https://wiki.qt.io/Qt_5.12_Tools_and_Versions
离线snow_man_0

只看该作者 10楼 发表于: 2020-04-21
试试用toLocal8Bit()
离线liulin188

只看该作者 11楼 发表于: 2020-04-21
回 snow_man_0 的帖子
snow_man_0:试试用toLocal8Bit() (2020-04-21 00:35) 

不是这里的问题
https://wiki.qt.io/Qt_5.12_Release
https://wiki.qt.io/New_Features_in_Qt_5.12
https://wiki.qt.io/Qt_5.12.0_Known_Issues
https://www.qt.io/blog/qt-5.13.2-released
https://www.qt.io/blog/qt-creator-4.10.2-released
https://wiki.qt.io/Qt_5.12_Tools_and_Versions
离线stlcours

只看该作者 12楼 发表于: 2020-04-21
QString s = 来源 ? 关键就是这个来源啊

如果使用 QString s = "mydata1\0\mydata2"; 按你的前一种方法,当然有问题。特别是,这个数据如果来自于文件或者其它不可知来源,就更容易出问题。请你告诉我,你的数据来源是什么?

有人说,编程其实就是在对字符串进行编程,事实差不多也是这样,很多很多的功能,我都是通过QString完成的,Qt官方称全世界有300万Qt程序员,我不信这么重要的utf8转换(没有之一!)还会出问题。所以最好你把来龙去脉都讲清楚,让我们帮你看一看。
离线j695858658

只看该作者 13楼 发表于: 2020-04-21
回 stlcours 的帖子
stlcours:
QString s = 来源 ? 关键就是这个来源啊
如果使用 QString s = "mydata1\0\mydata2"; 按你的前一种方法,当然有问题。特别是,这个数据如果来自于文件或者其它不可知来源,就更容易出问题。请你告诉我,你的数据来源是什么?
有人说,编程其实就是在对字符串进行编程,事实差不多也是这样,很多很多的功能,我都是通过QString完成的,Qt官方称全世界有300万Qt程序员,我不信这么重要的utf8转换(没有之一!)还会出问题。所以最好你把来龙去脉都讲清楚,让我们帮你看一看。
.......

确实有可能是这样的 QString不能接受含有\0的字符 确实会有问题的。


离线liulin188

只看该作者 14楼 发表于: 2020-04-21
回 stlcours 的帖子
stlcours:
QString s = 来源 ? 关键就是这个来源啊
如果使用 QString s = "mydata1\0\mydata2"; 按你的前一种方法,当然有问题。特别是,这个数据如果来自于文件或者其它不可知来源,就更容易出问题。请你告诉我,你的数据来源是什么?
有人说,编程其实就是在对字符串进行编程,事实差不多也是这样,很多很多的功能,我都是通过QString完成的,Qt官方称全世界有300万Qt程序员,我不信这么重要的utf8转换(没有之一!)还会出问题。所以最好你把来龙去脉都讲清楚,让我们帮你看一看。
.......


请看我5楼的代码,来源就是texteidt里的字符(全部是正常的字母数字)
我也没说是tuUtf8有问题,只是说QString转成的char *直接作为参数用于c库函数调用存在不稳定性!
https://wiki.qt.io/Qt_5.12_Release
https://wiki.qt.io/New_Features_in_Qt_5.12
https://wiki.qt.io/Qt_5.12.0_Known_Issues
https://www.qt.io/blog/qt-5.13.2-released
https://www.qt.io/blog/qt-creator-4.10.2-released
https://wiki.qt.io/Qt_5.12_Tools_and_Versions
离线liulin188

只看该作者 15楼 发表于: 2020-04-21
回 j695858658 的帖子
j695858658:确实有可能是这样的 QString不能接受含有\0的字符 确实会有问题的。
[图片]
 (2020-04-21 09:29) 

看我5楼的代码
https://wiki.qt.io/Qt_5.12_Release
https://wiki.qt.io/New_Features_in_Qt_5.12
https://wiki.qt.io/Qt_5.12.0_Known_Issues
https://www.qt.io/blog/qt-5.13.2-released
https://www.qt.io/blog/qt-creator-4.10.2-released
https://wiki.qt.io/Qt_5.12_Tools_and_Versions
离线goodname

只看该作者 16楼 发表于: 2020-04-21
qt的用法没问题,同意curl的函数用法和注意事项仔细研究研究。
即使是你换成数组,也只是看起来没问题,实际上用法也未必对。
离线liulin188

只看该作者 17楼 发表于: 2020-04-21
回 goodname 的帖子
goodname:qt的用法没问题,同意curl的函数用法和注意事项仔细研究研究。
即使是你换成数组,也只是看起来没问题,实际上用法也未必对。
 (2020-04-21 17:10) 

对,你说的极有可能是对的,我把范围扩大点去查
https://wiki.qt.io/Qt_5.12_Release
https://wiki.qt.io/New_Features_in_Qt_5.12
https://wiki.qt.io/Qt_5.12.0_Known_Issues
https://www.qt.io/blog/qt-5.13.2-released
https://www.qt.io/blog/qt-creator-4.10.2-released
https://wiki.qt.io/Qt_5.12_Tools_and_Versions
离线liulin188

只看该作者 18楼 发表于: 2020-04-22
今天回不了帖子啊
https://wiki.qt.io/Qt_5.12_Release
https://wiki.qt.io/New_Features_in_Qt_5.12
https://wiki.qt.io/Qt_5.12.0_Known_Issues
https://www.qt.io/blog/qt-5.13.2-released
https://www.qt.io/blog/qt-creator-4.10.2-released
https://wiki.qt.io/Qt_5.12_Tools_and_Versions
离线liulin188

只看该作者 19楼 发表于: 2021-09-05
妈的,时隔一年多,这个帖子结帖了,就是作用域的问题
https://wiki.qt.io/Qt_5.12_Release
https://wiki.qt.io/New_Features_in_Qt_5.12
https://wiki.qt.io/Qt_5.12.0_Known_Issues
https://www.qt.io/blog/qt-5.13.2-released
https://www.qt.io/blog/qt-creator-4.10.2-released
https://wiki.qt.io/Qt_5.12_Tools_and_Versions
快速回复
限100 字节
 
上一个 下一个