将上面的表用二维数组标识
时间: 2023-10-03 21:06:55 浏览: 88
可以将上面的表用二维数组来表示。数组的每一行表示一个GBK编码范围,第一列是最小GBK编码,第二列是最大GBK编码,第三列是对应的UTF-8编码范围的第一个字节,第四列是第二个字节,第五列是第三个字节。下面是对应的代码示例:
```C++
#include <Arduino.h>
const uint16_t GBK2UTF8_Table[][5] PROGMEM = {
// GBK编码范围 UTF-8编码范围(二进制)
{0xA1A1, 0xE7C0, 0xC2, 0xA1, 0x80},
{0xA1C0, 0xE7C1, 0xC2, 0xA1, 0x81},
{0xA1F4, 0xE7C2, 0xC2, 0xA1, 0x82},
// ... 其它编码范围的转换
{0xFEFE, 0xE7FE, 0xC2, 0xA1, 0xFE},
};
void GBK2UTF8(const char* gbkStr, char* utf8Str) {
uint8_t gbkByte1, gbkByte2;
uint8_t utf8Byte1, utf8Byte2, utf8Byte3;
while (*gbkStr) {
gbkByte1 = *gbkStr++;
if (gbkByte1 < 0x80) {
// ASCII字符,直接转换
*utf8Str++ = gbkByte1;
continue;
}
gbkByte2 = *gbkStr++;
// 在查表中查找GBK编码范围对应的UTF-8编码范围
uint16_t gbkCode = (gbkByte1 << 8) | gbkByte2;
uint16_t minGbk, maxGbk, minUtf8, maxUtf8;
bool found = false;
for (int i = 0; i < sizeof(GBK2UTF8_Table) / sizeof(GBK2UTF8_Table[0]); i++) {
minGbk = pgm_read_word_near(&GBK2UTF8_Table[i][0]);
maxGbk = pgm_read_word_near(&GBK2UTF8_Table[i][1]);
if (gbkCode >= minGbk && gbkCode <= maxGbk) {
minUtf8 = pgm_read_word_near(&GBK2UTF8_Table[i][2]);
maxUtf8 = pgm_read_word_near(&GBK2UTF8_Table[i][3]);
found = true;
break;
}
}
if (!found) {
// 不在查表范围内,直接输出原GBK字符
*utf8Str++ = gbkByte1;
*utf8Str++ = gbkByte2;
continue;
}
// 查表得到UTF-8编码值
uint16_t offset = gbkCode - minGbk;
utf8Byte1 = minUtf8 + (offset >> 12);
utf8Byte2 = ((offset >> 6) & 0x3F) + ((gbkByte1 & 0x03) << 4);
utf8Byte3 = (offset & 0x3F) + ((gbkByte2 & 0x3F) << 2);
*utf8Str++ = utf8Byte1;
*utf8Str++ = utf8Byte2;
*utf8Str++ = utf8Byte3;
}
*utf8Str = '\0';
}
```
这个函数的实现与之前的版本类似,只是查表的方式与数据结构不同。在查表时需要遍历整个二维数组,找到对应的GBK编码范围,然后得到对应的UTF-8编码范围。在得到UTF-8编码值时,需要根据偏移量和原始的GBK编码值计算出每个字节的值。
阅读全文