我给出了一个Qt项目,该项目需要支持波斯语。从服务器发送数据并使用第一行,我得到一个QByteArray并使用第二行将其转换为QString:
function playerStart() {
var widget = Mixcloud.PlayerWidget(document.getElementById("mmnMixPlayer"));
widget.ready.then(function() {
// Put code that interacts with the widget here
play();
});
/* AJAX link click */
jQuery(document).on("click", "a[target!='_blank']:not(a[href^='#'])", function(e){
var link = jQuery(this).attr("href");
// var title = jQuery(responseHtml).filter('title').text();
// console.log(title);
jQuery("#content").load( link + " #content", function(responseText) {
var newtitle = escapeHtml(responseText.match(/<title>([^<]*)/)[1]);
document.title = newtitle; }
);
e.preventDefault();
history.pushState({}, null, link);
// jQuery(document).find("title").text(jQuery(responseHtml).filter('title').text());
});
}
function playerStop() {
var widget = Mixcloud.PlayerWidget(document.getElementById("mmnMixPlayer"));
widget.ready.then(function() {
// Put code that interacts with the widget here
pause();
});
}
jQuery(document).on("click", "#listengomb.stopped", function(e){
playerStart();
jQuery(this).removeClass("stopped").addClass("playing");
e.preventDefault;
})
jQuery(document).on("click", "#listengomb.playing", function(e){
playerStop();
jQuery(this).removeClass("playing").addClass("stopped");
e.preventDefault;
})
以英语发送数据时,一切都很好,但是以波斯语代替
QByteArray readData = socket->readAll();
QString DataAsString = QTextCodec::codecForUtfText(readData)->toUnicode(readData);
我知道
سلام
我提到了此过程,因此人们不会建议使用.tr的多语言应用程序的制作方法。都是关于文本和解码的,而不是那些翻译方法。我的操作系统是Windows 8.1(对于您需要了解的情况)。
当服务器发送سلام
时,我得到这个十六进制值سÙ\u0084اÙ\u0085
由于我不知道的原因,通过服务器的方式在开头发送了两个额外的字节。所以我用以下方法切断了它:
0008d8b3d984d8a7d985
在将其转换为QString之后,十六进制值在开始时会有一些额外的作用。
答案 0 :(得分:7)
我对等待回复感到好奇,并独自开玩笑:
我复制了文本سلام
(英语:“ Hello”),并将其粘贴到Nodepad ++(在我的情况下使用UTF-8编码)。然后我切换到以十六进制查看并得到:
右侧的ASCII转储看起来有点类似于OP意外获得的内容。这让我相信readData
中的字节是用UTF-8编码的。因此,我采用了暴露的十六进制数字,并制作了一些示例代码:
testQPersian.cc
:
#include <QtWidgets>
int main(int argc, char **argv)
{
QByteArray readData = "\xd8\xb3\xd9\x84\xd8\xa7\xd9\x85";
QString textLatin1 = QString::fromLatin1(readData);
QString textUtf8 = QString::fromUtf8(readData);
QApplication app(argc, argv);
QWidget qWin;
QGridLayout qGrid;
qGrid.addWidget(new QLabel("Latin-1:"), 0, 0);
qGrid.addWidget(new QLabel(textLatin1), 0, 1);
qGrid.addWidget(new QLabel("UTF-8:"), 1, 0);
qGrid.addWidget(new QLabel(textUtf8), 1, 1);
qWin.setLayout(&qGrid);
qWin.show();
return app.exec();
}
testQPersian.pro
:
SOURCES = testQPersian.cc
QT += widgets
已在Windows 10的cygwin中进行了编译和测试:
$ qmake-qt5 testQPersian.pro
$ make
$ ./testQPersian
同样,Latin-1的输出看起来与OP以及Notepad ++公开的输出类似。
UTF-8的输出提供了预期的文本(符合预期,因为我提供了正确的UTF-8编码作为输入)。
也许是,ASCII / Latin-1输出的变化有点令人困惑。 –存在多个字符字节编码,它们在下半部分(0 ... 127)共享ASCII,但在上半部分(128 ... 255)具有不同的字节含义。 (请看ISO/IEC 8859来理解我的意思。在Unicode成为本地化问题的 final 解决方案流行之前,这些已作为本地化引入。)
波斯语字符肯定具有超过127的所有Unicode代码点。(Unicode也共享前128个代码点的ASCII。)此类代码点在UTF-8中编码为多个字节的序列,其中每个字节都有MSB(最高有效位–位7)设置。因此,如果用任何ISO8859编码(偶然地)解释了这些字节,那么上半部分就变得有意义。因此,根据当前使用的ISO8859编码,这可能会产生不同的字形。
一些延续:
OP发送了以下快照:
所以,似乎代替了
d8 b3 d9 84 d8 a7 d9 85
他有
00 08 d8 b3 d9 84 d8 a7 d9 85
可能的解释:
服务器首先发送16位长度的00 08
–解释为Big-Endian 16位整数: 8 ,然后是 8 个以UTF编码的字节-8(与我在上面玩过的游戏一模一样)。
(AFAIK,对于发送方和接收方本来就有不同的字节序,使用Big-Endian二进制网络协议来防止字节序问题并不稀奇。)此处:htons(3) - Linux man page
在i386上,主机字节顺序是最低有效字节在前,而在Internet上使用的网络字节顺序是最高有效字节在前。
OP声称已使用此协议DataOutput – writeUTF:
将两个字节的长度信息写入输出流,然后是字符串s中每个字符的修改后的UTF-8表示形式。如果s为null,则抛出NullPointerException。字符串s中的每个字符都将转换为一个,两个或三个字节的组,具体取决于字符的值。
所以,解码看起来像这样:
QByteArray readData("\x00\x08\xd8\xb3\xd9\x84\xd8\xa7\xd9\x85", 10);
//QByteArray readData = socket->readAll();
unsigned length
= ((uint8_t)readData[0] << 8) + (uint8_t)readData[1];
QString text = QString::fromUtf8(dataRead.data() + 2, length);
前两个字节是从readData
中提取出来的,并组合到length
中(解码大尾数16位整数)。
dataRead
的其余部分将转换为QString
,提供先前提取的length
。因此,readData
的前2个长度字节被跳过。
答案 1 :(得分:0)
您需要像这样用utf8发送数据
mysocket->write(message.toUtf8());
并像这样接收并转换为utf8:
QByteArray Data = mysocket->readAll();
QString DataAsString = QString::fromUtf8(Data);
您的数据将被发送而不会变得无法识别