首先需要了解什么是unicode
unicode是一种字符集,它包含了世界上几乎所有的字符的标准集合。每一个字符都有与之对应的编码。
unicode编码就是,unicode字符集中字符对应的码号。通常用16进制表示;
eg:
汉字:飞
对应的unicode编码:98DE (16进制)
1001 1000 1101 1110
UTF-8是什么
UTF8是一种针对unicode字符集设计的可变长度字符编码方案。
UTF8对应汉字的编码格式一般占用3或4个字节,大部分是3个字节
eg:
汉字:飞
对应的UTF-8编码:e9a39e
1110 1001 1010 0011 1001 1110
对应的UTF-8编码格式: \xe9\xa3\x9e
既然说UTF8是unicode字符集大的一种编码方案 那么如何通过UTF8编码查找对应的unicode编码从而获取对应的符号(汉字)
1. **识别字节顺序和长度**:
- 对于UTF-8编码,每个字符根据其Unicode码点范围使用不同数量的字节进行编码。
- 单字节:U+0000至U+007F,编码为`0xxxxxxx`
- 双字节:U+0080至U+07FF,编码为`110xxxxx 10xxxxxx`
- 三字节:U+0800至U+FFFF,编码为`1110xxxx 10xxxxxx 10xxxxxx`
- 四字节:U+10000至U+10FFFF,编码为`11110xxx 10xxxxxx 10xxxxxx 10xxxxxx`
2. **解码过程**:
- 遍历UTF-8字符串的每个字节。
- 根据首位的1的数量确定后续字节的数量和模式。
- 分别从每个字节中提取有效位并拼接起来,形成最终的Unicode码点
eg:
- UTF-8编码1110 1001 1010 0011 1001 1110 将1.中的xx取出来得到 1001 1000 1101 1110就是对应unicode编码
代码中碰到的具体问题
wifi模块中将wifi中的ssid已char[]数组存起来,char[]数组中的内容是“\\xe9\\xa3\\x9e”
char ssid[200] = "\\xe9\\xa3\\x9e"
如何将他转换成“飞”存到QString中去
1. 先使用QString::fromLocal8Bit函数,将字符串以字节为单位转换成对应的字符串
QString str_ssid = QString::fromutf8(ssid);//str_ssid中包含的字符就是“\xe9\xa3\x9e”,注意这里的\是包含在里面的字符而不是分隔符
2.现在需要对字符串 “\xe9\xa3\x9e”进行处理 变成““e9a39e””,用16进制的格式存到分别存到3个字节中,这样才能识别出中文来
以下是实现的函数
QString process(QString strResStr)
{
//strResStr中存放的是\xe9\xa3\x9e
QString str_temp;
for(int i = 0 ; i <strResStr.length;)
{
if(strResStr.at(i) == "\\") //如果当前位置为\
{
if((i+1) < strResStr.length() && strResStr.at(i+1) == '\\') //连续两个\一般不会进入
{
//这里做的操作就是将两个连续的\替换为1个\
str_stemp.append(strResStr.at(i)) // 将一个\加到字符串里
i+=2;
}
else if((i+1) < strResStr.length() && strResStr.at(i+1) != 'x')
{
//说明轮到英文了 ,就contine添加英文
++i;
contine;;
}
else
{ //处理中文utf-8
QString str = strResStr.mid(i+2,i+4);
strResStr.append(str.mid(0,2).toUShort(0,16))//将获得的字符以16进制的形式存到代码中
i+=4;
}
}
else
{
//添加英文或数字这种不是多字节编码格式的字符
str_temp.append(strResStr.at(i));
i++;
}
}
//str_temp 中存放的是e9a39e
QByteArry latin1 = str_temp.toLatin1();
//这时候p里面存着的就是真正的值
char* p = latin1.data();
//然后通过编码转换将他转换成中文格式并且返回出去
return QString::fromUtf8(p);
}