QString 波斯语

2023-11-24

我给出了一个需要支持波斯语的 Qt 项目。数据从服务器发送并使用第一行,我得到一个 QByteArray 并使用第二行将其转换为 QString:

    QByteArray readData = socket->readAll();
    QString DataAsString = QTextCodec::codecForUtfText(readData)->toUnicode(readData);

当发送的数据是英语时,一切都很好,但是当发送的是波斯语时,而不是

سلام

I get

سÙ\u0084اÙ\u0085

我提到了这个过程,这样人们就不会建议制作使用 .tr 的多语言应用程序的方法。这一切都与文本和解码有关,而不是那些翻译方法。我的操作系统是Windows 8.1(如果你需要知道的话)。

当服务器发送时我得到这个十六进制值

0008d8b3d984d8a7d985

顺便说一下,服务器在开始时发送了两个额外的字节,原因我不知道。所以我用以下方法将其切断:

DataAsString.remove(0,2);

在它被转换为 QString 之后,十六进制值在乞求时有一些额外的。


我非常好奇地等待回复,并自己玩了一下:

我复制了文字سلام(英语:“Hello”)并将其粘贴到 Nodepad++(在我的例子中使用 UTF-8 编码)。然后我切换到查看十六进制并得到:

snapshot of Notepad++ - hex dump of "سلام"

右侧的 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

编译并测试于cygwin在 Windows 10 上:

$ qmake-qt5 testQPersian.pro

$ make

$ ./testQPersian

snapshot of 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发送了以下快照:

Snapshot (provided by OP)

所以,看起来而不是

d8 b3 d9 84 d8 a7 d9 85

he got

00 08 d8 b3 d9 84 d8 a7 d9 85

一种可能的解释:

服务器首先发送一个16位长度00 08– 解释为大端字节序16 位整数:8, then 8以 UTF-8 编码的字节(看起来与我上面玩的一模一样)。 (AFAIK,如果发送方和接收方具有不同的字节顺序,那么使用 Big-Endian 进行二进制网络协议来防止字节顺序问题并不罕见。)这里:htons(3) - Linux 手册页

在 i386 上,主机字节顺序是最低有效字节在前,而 Internet 上使用的网络字节顺序是最高有效字节在前。


OP声称使用了该协议数据输出 – 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);
  1. 前两个字节是从readData并结合到length(解码大端 16 位整数)。

  2. 其余的dataRead被转换为QString提供之前提取的length。因此,前 2 个长度字节readData被跳过。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

QString 波斯语 的相关文章

  • 使用可加载内核模块修改帧缓冲区(/dev/graphics/fb0)参数

    Problem 我必须配置 Android 平台使用的各种 LCD 显示器 几乎在所有情况下 都没有针对感兴趣的 LCD 显示器免费提供的电气规格 但通过经验和逆向工程 可以很好地猜测参数 我正在尝试使用可加载内核模块来微调显示参数 也欢迎
  • 求 a 范围内的 pow(a^b)modN

    对于给定的b and N以及一系列a say 0 n 我需要找到ans 0 n 1 where ans i 没有a s为此pow a b modN i 我在这里搜索的是可能的重复pow a b modN对于一系列a 以减少计算时间 例子 i
  • 以编程方式更改 Excel 中的字体(Trebuchet MS、Calibari)C#

    我目前正在使用一个 C 应用程序 该应用程序有一个将生成 Excel 文件的类 一切都很顺利 Excel 工作表上填充的数据具有 Times New Roman 字体 我想将其更改为其他字体 Calibari 我怎样才能以编程方式做到这一点
  • 如何将 CroppedBitmap 转换为 BitmapImage

    我正在尝试将 CroppedBitmap 转换为 BitmapImage 编辑 不使用内存流 我尝试过直接转换它 似乎这不是一个选择 这应该没那么难 我正在尝试剪切 BitmapImage 的一部分 并创建一个仅包含新裁剪的 Bitmap
  • 运行时两个注册之间的简单注入器基于动态上下文的注入

    我有一个使用 Simple Injector 进行命令处理程序注册的中介应用程序 并且注入和处理程序均已设置并完美运行 class DoWashingCommandHandler IRequestHandler
  • 指向指针的指针和指向二维数组的指针之间的区别

    如果我有一个二维数组 B 定义为 int B 2 3 1 3 5 2 4 6 Is int p B与 一样int p 3 B int f B printf d f 1 gives 5作为输出 同时printf d f 给出 1 作为答案 为
  • 错误 C2065:'cout':未声明的标识符

    我正在处理我的编程作业的 驱动程序 部分 但我不断收到这个荒谬的错误 错误 C2065 cout 未声明的标识符 我什至尝试过使用std cout但我收到另一个错误 IntelliSense 命名空间 std 没有成员 cout 当我宣布u
  • 如何处理作为参数传递到方法中的 Lambda 表达式 - C# .NET 3.5

    我对 Lambda 表达式的了解有点不稳定 虽然我可以编写使用 Lambda 表达式 又名 LINQ 的代码 但我正在尝试编写自己的方法 该方法采用一些 Lambda 表达式类型的参数 背景 我正在尝试编写一个方法 该方法从任何其他对象类型
  • VS2010中VSHost.exe不断启动

    我正在 VS2010 中使用一个包含大量项目的解决方案 但它不断变得无响应 我注意到的一件事可能是一条线索 尽管我尚未开始任何调试 但 MyApplicationName vshost exe 不断出现在进程列表中 也许每当构建发生时它就会
  • 如何将 QSerialPort 模块添加到 CMake 中?

    我想将 QSerialPort 模块添加到 CMake 中 根据我的理解 我需要将QT 串口添加到 pro中 我只想使用 CMake 所以我尝试编译简单的 CMake 文件 但有错误 QtCore 正在工作 qDebug 可以毫无问题地显示
  • 如果 .txt 文件不存在,则创建一个,如果存在则追加新行

    我想创建一个 txt 文件并写入它 如果该文件已经存在 我只想添加更多行 string path E AppServ Example txt if File Exists path File Create path TextWriter t
  • ASP.NET 中的 thread.sleep

    我正在为我的网站模拟彗星实时馈送协议 因此在我的控制器中我添加 while nothing new before timeout Thread Sleep 1000 但我注意到添加此功能后整个网站变慢了 调试后我得出结论 当我打电话时Thr
  • 持续运行的 C# 代码 - 服务还是单独的线程?

    我有一个 NET 4 Web 应用程序 它有 3 个关联的独立项目 DAL BAL 和 UI 我正在使用实体框架进行数据库交互 我有代码循环遍历一堆数据库数据 根据找到的内容调用方法 然后更新数据库 我希望这段代码一直运行 同时 我希望用户
  • 如何在 WCF 中反序列化自定义 SOAP 标头?

    我正在尝试向通过 WCF 的所有 SOAP 请求添加自定义标头 我发现这篇精彩的文章 http blogs msdn com b mohamedg archive 2012 10 21 adding custom soap headers
  • 如何“全局”捕获对象实例中引发的异常

    我目前正在编写一个 winforms 应用程序 C 我正在使用企业库异常处理块 遵循我所看到的相当标准的方法 IE 在 Program cs 的 Main 方法中 我已将事件处理程序连接到 Application ThreadExcepti
  • 剥离 OLE 标头信息 (MS Access / SQL Server)

    我有一个 C 应用程序需要支持二进制数据库内容 图像等 当使用 MS Access 或 MS SQL Server 时 此数据被包装在 OLE 对象内 如何去除此 OLE 标头信息 请注意 我不能只查找特定标签的开头 因为内容可以是 png
  • 如何通过 Excel 互操作对象自动调整列大小?

    下面是我用来将数据加载到 Excel 工作表中的代码 但我希望在加载数据后自动调整列的大小 有谁知道自动调整列大小的最佳方法 using Microsoft Office Interop public class ExportReport
  • 将 R 值传递给采用 L 值的函数时出现过载歧义

    我有 2 个重载函数 一个采用 L 值 另一个采用 R 值 目的是让该函数可以像这样调用 Obj obj foo obj OR foo Obj 所以 我写了2个重载函数 template
  • 更快的 WinSock sendto()

    我使用的是 Windows Server 2008 我的程序是用 C 编写的 我在 while true 循环中使用 WinSock2 和 sendto 来发送数据包 代码如下 while true if c snd gt max c sn
  • RC4 实现与 openssl 输出不匹配

    我的目标是在 C C 中实现 RC4 流密码 并确保它产生与使用时相同的输出openssl命令 按照伪代码维基百科 https en wikipedia org wiki RC4 该实现似乎有效 因为它可以加密和解密内容 但是 加密的输出与

随机推荐