程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> std::string在多字節字符集環境下substr的實現方法,stdsubstr

std::string在多字節字符集環境下substr的實現方法,stdsubstr

編輯:C++入門知識

std::string在多字節字符集環境下substr的實現方法,stdsubstr


昨天寫到《使用多字節字符集的跨平台(PC、Android、IOS、WP)編碼/解碼方法》中提到服務端使用std::string處理字符串,std::string對多字節字符集支持並不是很完善,std::string中的函數沒有對多字節字符集進行直接的支持。

例如直接調用std::string的substr函數,就會導致某些情況下截取的字符串尾部產生非法字符。

GB系列多字節字符集基礎知識:

VC環境下工程設置為多字節字符集,默認使用的是GBK編碼,GB2312、GBK、GB18030,這3個都是中文編碼方式,並向下兼容。

1、GB2312包含7000多個漢字和字符,GBK包含21000多個,GB18030包含27000多個。

2、GBK中的中文字符是雙字節來表示的,英文字符是用ASCII碼表示的,也就是單字節表示的。

3、GBK編碼表中也有英文字符的雙字節表示形式,所以英文字母可以有2中GBK表示方式。

4、GBK編碼中的中文字符將其最高位都定成1,英文字符單字節最高位都為0。

5、當用GBK解碼時,若高字節最高位為0,則用ASCII碼表解碼;若高字節最高位為1,則用GBK編碼表解碼。

以上5點就可以解釋了std::string中substr為什麼會在尾部產生非法字符的問題了,substr只考慮了字節長度,沒考慮多字節字符集編碼。

對於使用substr截斷的字符串,在IOS環境下使用NSString初始化時會失敗,而Android的String類型則會容忍非法字符。

為了徹底解決平台兼容性問題,必須自己實現截取函數:

int GbkSubString(const char *s, int iLeft)  
{  
	int len = 0, i = 0;  

	if( s == NULL || *s == 0 || iLeft <= 0 )   
		return(0);  

	while( *s )  
	{  
		if( (*s & 0x80) == 0 )  
		{  
			i ++;  
			s ++;  
			len ++;  
		}  
		else  
		{  
			if( *(s + 1) == 0 ) break;  

			i += 2;  
			s += 2;  
			len += 2;  
		}  

		if( i == iLeft ) break;  
		else if( i > iLeft )  
		{  
			len -= 2;  
			break;  
		}  
	}  

	return(len);  
}  

先使用GbkSubString函數對長度進行處理,再使用返回的准確長度調用substr。


 

記錄,為更好的自己!

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved