破晓 发表于 2015-1-16 14:05:02

字符串逐字刷新

在做游戏剧情展示的时候遇到一种需求把游戏对话逐字显示给玩家,效果如下:




实现这种效果的方式就是把一个字符串逐个中文取出来刷新到屏幕上,研究了各种编码之后发现UTF8的编码非常简单也很容易逐个/中文/英文/符号读取.首先看看UTF8非常简单的编码方式:

[*]对于单字节的符号,字节的第一位设为0,后面7位为这个符号的unicode码。因此对于英语字母,UTF-8编码和ASCII码是相同的。
[*]对于n字节的符号(n>1),第一个字节的前n位都设为1,第n+1位设为0,后面字节的前两位一律设为10。剩下的没有提及的二进制位,全部为这个符号的unicode码。
UTF8编码规则

      Unicode符号范围
         UTF-8编码方式
   
(十六进制)
(二进制)

0000 0000-0000 007F
0xxxxxxx

0000 0080-0000 07FF
110xxxxx 10xxxxxx

0000 0800-0000 FFFF
1110xxxx 10xxxxxx 10xxxxxx

0001 0000-0010 FFFF
11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

按照规则可以使用如下算法算出一个中文所占的字符:
/// 获取utf8字符长度
int getUtf8Length( const char* pszutf8 )
{
    if( pszutf8 == NULL )
    {
      return 0;
    }

    for( int i = 8; i > 0; --i )
    {
      unsigned char c = 1 < < (i - 1);
      if( ( pszutf8 & c ) != c )
      {
            if( i == 8 )
            {
                return 1;
            }
            else
            {
                return 8 - i;
            }
      }
    }

    return 1;
}
void Main()
{
    std::string strSrc = "我在马路边";
    if( strSrc.empty() )
    {
      return;
    }
    size_t size = strSrc.length();
    for( size_t i = 0; i < size; )
    {
      const unsigned char c = strSrc.at(i);
      int len = getUtf8Length((const char*)&c);

      i += len;

      std::string strTemp = strSrc.substr( 0, i );
      printf("%s\n",strTemp.c_str());
      
    }
}打印出来可以看到:

我在
我在马
我在马路
我在马路边基本实现想要的展示效果.但是要求是必须输入的字符串是UTF8格式..


参考文章



[*]字符编码笔记:ASCII,Unicode和UTF-8
[*]字符编解码的故事
[*]纯LUA的UTF8字符串截断方法



本文来自:http://shadowkong.com/archives/1888


页: [1]
查看完整版本: 字符串逐字刷新