GBK和Utf-8字符串截取函數

工作中用到了,就寫了一個。

GBK編碼從0x8140-0xFEFE,去除0xxx7F這部分。包括了所用的中日韓字符集。

判斷是否爲GBK可以用isGBKChe 或 isGBKChe2,都可以。

一個是從區間判斷,一個是從第一個字節的頭位爲一這個特性判斷。

typedef     unsigned char var_u1;
#define isZone(p,a,b) ( (p) >= (a) && (p) <= (b) )
#define isGBKChe(p) (isZone(*(var_u1*)p,0x81,0xFE) && isZone(*(var_u1*)(p+1),0x40,0xFE) && *(p+1) != 0x7F )
#define isGBKChe2(p) (*(p)<0)


static int cutbuf(char* p, int len, int size)
{
 if( len<= size )
  return len;

 char *pEnd = p + size - 1;
 char *pCur = p;

 if( !isGBKChe(pEnd) )
  return size;
 
 while(pCur<pEnd)
 {
  if( isGBKChe(pCur) )
   pCur+=2;
  else
   pCur++;
 }
 
 return pCur-p; 
}


utf-8判斷遵循的是這個屬性:

UTF-8的編碼規則很簡單,只有二條:

1)對於單字節的符號,字節的第一位設爲0,後面7位爲這個符號的unicode碼。因此對於英語字母,UTF-8編碼和ASCII碼是相同的。

2)對於n字節的符號(n>1),第一個字節的前n位都設爲1,第n+1位設爲0,後面字節的前兩位一律設爲10。剩下的沒有提及的二進制位,全部爲這個符號的unicode碼。

下表總結了編碼規則,字母x表示可用編碼的位。

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

漢字位於第三區間內,由三字節編碼組成。

所以只要鑑別第一字節的頭四個字位,後兩位的前兩個字位即可。

#define isUTF8Che(p) ( (*(var_u1*)(p))>>4 == 0x0E && (*(var_u1*)(p+1))>>6 == 0x02 && (*(var_u1*)(p+2))>>6 == 0x02 )

static int qi_cutbuf_utf8(var_1* p, int len, int size)
{
	if( len<= size )
		return len;
	
	if( *(p + size - 1) >= 0 )
		return size;
	
	if( size < 3 )
		return 0;

	char *pEnd = p + size;
	char *pCur = p + size - 2;

	while(pCur>p && (*(var_u1*)(pCur))>>4 != 0x0E )
	{
		pCur--;
	}

	while(pCur<pEnd)
	{
		if( isUTF8Che(pCur) )
			pCur+=3;
		else
			pCur++;
	}

	if( pCur > pEnd )
		pCur -= 3;
	
	return pCur-p;	
}

中間做了個優化,

1.如果截取末尾爲正數,可以認爲該字符爲單字符編碼,直接截取即可。

2.如果小於3字節,返回0長度。

3.向前找1110 xxxx或大於零的字節,然後從該位置向後計算,這樣可以不用從頭遍歷。

 

這兩個文章是介紹編碼字符集的:

 字符編碼簡介:ASCII,Unicode,UTF-8,GB2312:http://www.cnblogs.com/mjgforever/archive/2008/02/27/1083135.html

字符集GBK和UTF8的區別說明:http://space.itpub.net/55022/viewspace-713901

 

發佈了24 篇原創文章 · 獲贊 12 · 訪問量 13萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章