基于UTF8字符串检查错误替换功能

来源:互联网 发布:js如何控制embed播放 编辑:程序博客网 时间:2024/05/17 21:53

utf8的长度为1~4个字节,是一种变长串,在转换和传送过程中,可能由于某种意外会导致串出现错误的字符,致使有些工具无法识别而出现乱码,或者直接导致操作无法完成。

实际应用中的例子:游戏中的邮件系统,一般会限制标题,内容的长度,但由于客户端截取长度时的不正当操作,导致utf8串被从中间截断。比如标题长度上限是15个字节,然后玩家输入的标题占用了16个字节,而最后输入的一个汉字占用3个字节,如果直接按长度截断就会出现最后一个汉字被截掉了一个字节。数据传到服务端之后,服务端存库时,数据库会进行字符检查,就会发现有不正确的字符,而导致插入数据失败。

解决办法:首先客户端那边字符截断的方法要按照utf8的格式来进行过滤截取,比如上面的例子,最后应该截取3个字节而不是1个。对于服务端这边,为了保证数据能正确插入,可以对不正确字符进行替换,比较合适的方法就是单个字节的字符替换,可以的话增加日志记录,便于查找错误根源。客户端的截取代码可以参考下面的服务端替换代码来写。

// 获取utf8字符长度int GetUTF8StrLen(IN const char chHead){if (0 == (0x80 & chHead)){return 1;}// 两个字节 110xxxxx 10xxxxxxelse if (0xc0 == (0xe0 & chHead)){return 2;}// 三个字节 1110xxxx 10xxxxxx 10xxxxxxelse if (0xe0 == (0xf0 & chHead)){return 3;}// 四个字节 11110xxx 10xxxxxx 10xxxxxx 10xxxxxxelse if (0xf0 == (0xf8 & chHead)){return 4;}return 0;}// 10xxxxxxbool IsUTF8SubChar(IN const char chSubChar){return (0x80 == (0xc0 & chSubChar));}//////////////////////////////////////////////////////////////////////////// UTF8字符串检查,注意pszString必须是utf8编码的字符串, chReplace为错误编码字符的替代符// 返回值标识有没有字符被替换bool UTF8Check(IN OUT char* pszString, const char chReplace /* = ' ' */){bool bHadReplaced = false;int nStrLen = strlen(pszString);if(nStrLen <= 0) return ;for (int i = 0; i < nStrLen;){char& chTmp = *(pszString + i);int nSubLen = GetUTF8StrLen(chTmp);// 头字节错误if (0 == nSubLen){chTmp = chReplace;i++;bHadReplaced = true;}// 1字节长度只要结构正确就没问题不用检查else if(1 == nSubLen) i++;// 超过1字节长度就要检查后面字节结构else if (nSubLen > 1){// 剩下字节长度不够,全部替换if ((i + nSubLen) > nStrLen){for (int k = i; k < nStrLen; k++) *(pszString + k) = chReplace;bHadReplaced = true;break;}int j = 1;for (; j < nSubLen; j++){char& chSubChar = *(pszString + i + j);// 不是正确的子字符,就替换当前chTmp对应的utf8字符if (false == IsUTF8SubChar(chSubChar)){nSubLen = j + 1;// 如果当前字符是下一个utf8头字符,就不替换当前字符if (GetUTF8StrLen(chSubChar) > 0) nSubLen--;for (int k = 0; k < nSubLen; k++) *(pszString + k + i) = chReplace;bHadReplaced = true;break;}}i += nSubLen;}}return bHadReplaced;}


0 0
原创粉丝点击