中文字符在MQL的处理

2021-06-23 00:30:13 浏览数 (1)

代码语言:javascript复制
“我花了两天时间,解决了一个中文字符在MQL下的解码问题”

众所周知中文字符需要用UTF8编码。

如果是用高级语言开发,那么基本不会遇到编解码问题,语言本身就帮你处理了这些细节。

但如果你用C语言,而且不允许用第三方库呢?

UT8和中文编码

以前的计算机只支持英文字符的时候,全部字符加符号也不过一两百个,ascii解决不了的,扩展一下表就可以了。

后来遇到了中文等其他语言,ascii就没辙了。动不动几万个字符,这咋整?

于是就有了UTF8编码。

比如"帅小伙",用UTF8编码是

代码语言:javascript复制
帅小伙

这是三个双字节的编码。

后台想把“帅小伙”通过json传给我,我在MQL里拿到的就是下面这串字符,

代码语言:javascript复制
u5E05u5C0Fu4F19

这里面的u表示转义字符是utf编码。

现在问题来了,只有基本的C语言类型和API,没有第三方库的情况下,怎么正确显示中文?

char转short,再位移一下

u5E05 来说,

在MQL里,拿到是是一个 char[],

代码语言:javascript复制
char[0] == '';
char[1] == 'u';
char[2] == '5';
char[3] == 'E';
char[4] == '0';
char[5] == '5';

简化处理流程,我们把转义字符忽略掉,只考虑后面四个char。

于是我们的问题变成要解决

5E05 -> 帅

众所周知,UTF8编码是1-4字节长度,对于常见中文占两字节。所以我们需要一个short类型来存最终结果。

最后我们想要拿到的是一个short变量ch,

代码语言:javascript复制
ushort ch = '帅';

从二进制角度把ch输出的话,会得到

代码语言:javascript复制
0101 1110 0000 0101

刚好对应 5E05 !

于是问题就进一步简化了,我们只需要把 char[] 按位移,然后按半字节做或处理就行。

最后的障碍

实际上 char[] 的字符本身还是编码,比如 '5',它是一个ascii编码,int值是53.

但这个问题不是很难,

只要把ascii编码按偏移量取值,就可以得到int值了。

因为'0'-'9',在ascii表里是连续的,从 48 到 57,只要把 char 减去48,就可以得到对应的int值。

到这里问题就解决了,

代码语言:javascript复制
ushort ch = 0101 1110 0000 0101;

char[0] 是 '5',转到ch的高位是 0101,取高位的代码

代码语言:javascript复制
(char[0] << 12) & 0xF000

剩下的12bit按同样的方式取就行。

有什么用?

现在的高级语言基本都会帮开发者处理掉这些编码细节问题,开发中基本不需要手动去解决编码转换的操作。

这种虽然方便了开发者,但也导致了很多开发者到现在都不知道基本类型占几个字节。

有个故事讲的是一个流水线遇到机器运行问题,请了一个老工程师。

老工程师收了五万块,去到流水线,用粉笔在机器上画了一条线,说,把这里拆开,里面的线圈减掉5匝。

工人不服,划一条线为什么要给这么多。

老工程师讲,划一条线,值五毛钱,但知道在哪里划线,值5万块。

0 人点赞