自己編寫的Windows字串類 封裝字串格式轉換和常用操作 方便使用

來源:互聯網
上載者:User

標籤:style   blog   http   ar   os   使用   sp   for   on   

最近開發的語音辨識的項目經常碰到轉碼的問題,各種寬窄位元組轉換,ASNI, UTF8, 寬位元組 ……  代碼寫得冗長,繁瑣,維護性太差了。決定自己寫一個能直接使用各種編碼的字串類,於是實現了一個,功能不多,但是也夠用。由於string 和 wstring 在多線程下共用資料會出問題,這裡只用最基礎的char 和 wchar_t。  

基於Windows平台,代碼如下


/***************************************************   Title: 自訂字串類************************************************** Date:2014/12/14************************************************** author:劉旭  **************************************************   Blog:http://blog.csdn.net/liuxucoder**************************************************  */ #ifndef __YKSTRING#define __YKSTRING#include <cstring>#include <new>#include <tchar.h>#include <strsafe.h>#include <Windows.h>#define MAX_COUNT  1024000typedef unsigned char BYTE;  //十進位轉十六進位inline BYTE Int_to_Hex(const BYTE src)  {  return src > 9 ? (src+55) : (src+48);  } 
//十六進位轉十進位inline BYTE Hex_to_Int(const BYTE &x)  {  return isdigit(x) ? x-'0' : x-'A'+10;  }  /**@自訂字串類*/class CYkString{public:/**@目的:字串轉碼,由 Ansi 轉為 wchar_t*@參數:const char* szAnsi轉碼前 Ansi 字串*@參數:wchar_t* szWchar轉碼後 wchar_t 字串*@傳回值: bool  成功返回true,失敗返回false*/bool Ansi_to_Wchar(const char* szAnsi,wchar_t*& szWchar){bool res = false;size_t nLen = MultiByteToWideChar(CP_ACP, NULL, szAnsi, -1, NULL, 0);wchar_t* strTemp  = NULL;nLen = (nLen+1)*sizeof(wchar_t);__try{if(NULL == (szWchar = new wchar_t[nLen])){__leave;}if(NULL == (strTemp = new wchar_t[nLen])){__leave;}ZeroMemory(szWchar, nLen);ZeroMemory(strTemp, nLen);if(0 == MultiByteToWideChar(CP_ACP, NULL, szAnsi, -1, strTemp, nLen)){__leave;}if(S_OK != StringCchCopyW(szWchar, nLen, strTemp)){__leave;}res = true;}__finally{if(NULL != strTemp){delete []strTemp;strTemp = NULL;}}return res;}/**@目的:字串轉碼,由 Utf-8 轉為 wchar_t*@參數:const char* szUtf8轉碼前 Utf-8 字串*@參數:wchar_t* szWchar轉碼後 wchar_t 字串*@傳回值: bool  成功返回true,失敗返回false*/bool Utf8_to_Wchar(const char* szUtf8,wchar_t*& szWchar){bool res = false;size_t nLen = MultiByteToWideChar(CP_UTF8, NULL, szUtf8, -1, NULL, 0);wchar_t* strTemp =NULL;nLen = (nLen+1)*sizeof(wchar_t);__try{if(NULL == (szWchar = new wchar_t[nLen])){__leave;}if(NULL == (strTemp = new wchar_t[nLen])){__leave;}ZeroMemory(szWchar, nLen);ZeroMemory(strTemp, nLen);if(0 == MultiByteToWideChar(CP_UTF8, NULL, szUtf8, -1, strTemp, nLen)){__leave;}if(S_OK != StringCchCopyW(szWchar, nLen, strTemp)){__leave;}res = true;}__finally{if(NULL != strTemp){delete []strTemp;strTemp = NULL;}}return res;}/**@目的:字串轉碼,由 wchar_t 轉為 Ansi*@參數:const wchar_t* szWchar轉碼前 wchar_t 字串*@參數:char* szAnsi轉碼後 Ansi 字串*@傳回值: bool  成功返回true,失敗返回false*/bool Wchar_to_Ansi(const wchar_t* szWchar,char*& szAnsi){bool res = false;size_t nLen = 0;char *strTemp = NULL;StringCchLengthW(szWchar, MAX_COUNT, &nLen);nLen = (nLen+1)*sizeof(wchar_t);__try{if(NULL == (szAnsi = new char[nLen])){__leave;}if(NULL == (strTemp = new char[nLen])){__leave;}ZeroMemory(szAnsi, nLen);ZeroMemory(strTemp, nLen);if( 0 == WideCharToMultiByte(CP_ACP, 0, szWchar, -1, strTemp, nLen, NULL, NULL)){__leave;}if(S_OK  != StringCchCopyA(szAnsi, nLen, strTemp)){__leave;}res = true;}__finally{if(NULL != strTemp){delete []strTemp;strTemp = NULL;}}return res;}/**@目的:字串轉碼,由 wchar_t 轉為 Utf-8*@參數:const wchar_t* szWchar轉碼前 wchar_t 字串*@參數:char* szUtf8轉碼後 Utf-8 字串*@傳回值: bool  成功返回true,失敗返回false*/bool Wchar_to_Utf8(const wchar_t* szWchar,char*& szUtf8){bool res = false;size_t nLen = 0;char *strTemp = NULL;StringCchLengthW(szWchar, MAX_COUNT, &nLen);nLen = (nLen+1)*2*sizeof(wchar_t);__try{if(NULL == (szUtf8 = new char[nLen])){__leave;}if(NULL == (strTemp = new char[nLen])){__leave;}ZeroMemory(szUtf8, nLen);ZeroMemory(strTemp, nLen);if( 0 == WideCharToMultiByte(CP_UTF8, 0, szWchar, -1, strTemp, nLen, NULL, NULL)){__leave;}if(S_OK  != StringCchCopyA(szUtf8, nLen, strTemp)){__leave;}res = true;}__finally{if(NULL != strTemp){delete []strTemp;strTemp = NULL;}}return  res;}/**@目的:字串轉碼,由 Ansi 轉為 Utf-8*@參數:const char * szAnsi  轉碼前 Ansi 字串*@參數:char* szUtf8 轉碼後 Utf-8 字串*@傳回值: bool  成功返回true,失敗返回false*/bool Ansi_to_Utf8(const char* szAnsi,char*& szUtf8){bool res = false;size_t nLen = 0;wchar_t* strTemp  = NULL;StringCchLengthA(szAnsi, MAX_COUNT, &nLen);__try{if(NULL == (strTemp = new wchar_t[nLen+1])){__leave;}if(false == Ansi_to_Wchar(szAnsi, strTemp)){__leave;}if(false == Wchar_to_Utf8(strTemp, szUtf8)){__leave;}res = true;}__finally{if(NULL != strTemp){delete []strTemp;strTemp = NULL;}}return res;}/**@目的:字串轉碼,由 Utf-8 轉為 Ansi*@參數:const char * szUtf8  轉碼前 Utf-8 字串*@參數:char* szAnsi轉碼後 Ansi 字串*@傳回值: bool  成功返回true,失敗返回false*/bool Utf8_to_Ansi(const char* szUtf8,char*& szAnsi){bool res = false;size_t nLen = 0;wchar_t* strTemp  = NULL;StringCchLengthA(szUtf8, MAX_COUNT, &nLen);__try{if(NULL == (strTemp = new wchar_t[nLen+1])){__leave;}if(false == (Utf8_to_Wchar(szUtf8, strTemp))){__leave;}if(false ==Wchar_to_Ansi(strTemp, szAnsi)){__leave;}res = true;}__finally{if(NULL != strTemp){delete []strTemp;strTemp = NULL;}}return res;}public:CYkString(size_t len = 256){Last_Style = Style_Char;IsAnsi = true;m_char = NULL;m_wchar = NULL;try{m_char = new char[len];m_wchar = new wchar_t[len];ZeroMemory(m_char, len);ZeroMemory(m_wchar, len);}catch(std::bad_alloc){if(m_char){delete []m_char;}if(m_wchar){delete []m_wchar;}throw;//此處拋出異常,停止建構函式,釋放資源}};~CYkString(void){if(NULL != m_char){delete []m_char;m_char = NULL;}if(NULL != m_wchar){delete []m_wchar;m_wchar = NULL;}};/**@目的: 重新整理字串,是每種字串儲存內容一致*@參數: 無*@傳回值: bool 成功返回 true  失敗返回 false*/bool FlushString(){if(Style_Char == Last_Style){if(false == IsAnsi){return Utf8_to_Wchar(m_char, m_wchar);}else{return Ansi_to_Wchar(m_char, m_wchar);}}else if(Style_WChar == Last_Style){if(false == IsAnsi){return Wchar_to_Utf8(m_wchar, m_char);}else{return Wchar_to_Ansi(m_wchar, m_char);}}}/**@目的:使用字串的char*格式*@參數:無*@傳回值: char* char*字串地址*/char*  asChar_str(){FlushString();Last_Style = Style_Char;return m_char;}/**@目的:使用字串的wchar_t*格式*@參數:無*@傳回值: wchar_t* wchar_t*字串地址*/wchar_t* asWchar_str(){FlushString();Last_Style = Style_WChar;return m_wchar;}/**@目的:返回字串的長度*@參數:無*@傳回值:size_t  字串的長度*/size_t GetLength(){FlushString();size_t nLen = 0;StringCchLengthW(m_wchar, MAX_COUNT, &nLen);return nLen;}/**@目的:判斷字串是否為空白*@參數:無*@傳回值:bool 空則返回true,非空則返回false*/bool IsEmpty(){FlushString();return GetLength() ? false : true;}/**@目的:將字串轉換為Ansi編碼形式*@參數:無*@傳回值: char* 轉碼後的字串*/char* ToAnsi(){FlushString();if(false == IsAnsi){IsAnsi = true;if(false == Utf8_to_Ansi(m_char, m_char)){m_char = NULL;}}return m_char;};/**@目的:將字串轉換為Utf-8編碼形式*@參數:無*@傳回值:char* 轉碼後的字串 */char* ToUtf_8(){FlushString();if(true == IsAnsi){IsAnsi = false;if(false == Ansi_to_Utf8(m_char, m_char)){m_char = NULL;}}return m_char;};/**@目的:將Utf-8格式字串用Urlcode編碼*@參數:無*@傳回值: char* 編碼後的字串*/char* UrlEncode_Utf8(){bool IsAnsiTemp = IsAnsi;ToUtf_8();char* result = NULL;  size_t nLen = 0;StringCchLengthA(m_char, MAX_COUNT, &nLen);size_t pos = 0;    //結果字串的長度標記  try{result = new char[(nLen+1)*sizeof(wchar_t)];ZeroMemory(result, sizeof(result));}catch(std::bad_alloc){delete []result;result = NULL;return result;}for(size_t i = 0; i < nLen; i++){  if(isalnum((BYTE)m_char[i]) || /*判斷是否為字母或者數字  必須進行類型轉換*/  ':' == m_char[i]|| '/' == m_char[i]|| '_' == m_char[i]   ||     '.' == m_char[i]||     '~' == m_char[i]||  '?' == m_char[i]||   '&' == m_char[i]||   '=' == m_char[i]   ){ result[pos++] = m_char[i];   //保持不變  }  else if(' ' == m_char[i]){//如果是空格  result[pos++] = '+';  }  else {//如果是其他字元  BYTE temp = Int_to_Hex((BYTE) m_char[i]);  result[pos++] = '%';  result[pos++] = Int_to_Hex((BYTE)m_char[i] >> 4);    result[pos++] = Int_to_Hex((BYTE)m_char[i] % 16);    }  }IsAnsi = IsAnsiTemp ? ToAnsi() : ToUtf_8();//恢複原來的編碼result[pos++] = '\0';return result;  }/**@目的:將Ansi格式字串用Urlcode編碼*@參數:無*@傳回值: char* 編碼後的字串*/char* UrlEncode_Ansi(){bool IsAnsiTemp = IsAnsi;ToAnsi();char* result = NULL;  size_t nLen = 0;StringCchLengthA(m_char, MAX_COUNT, &nLen);size_t pos = 0;    //結果字串的長度標記  try{result = new char[(nLen+1)*sizeof(wchar_t)];ZeroMemory(result, sizeof(result));}catch(std::bad_alloc){delete []result;result = NULL;return result;}for(size_t i = 0; i < nLen; i++){  if(isalnum((BYTE)m_char[i]) || /*判斷是否為字母或者數字  必須進行類型轉換*/  ':' == m_char[i]|| '/' == m_char[i]|| '_' == m_char[i]   ||     '.' == m_char[i]||     '~' == m_char[i]||  '?' == m_char[i]||   '&' == m_char[i]||   '=' == m_char[i]   ){ result[pos++] = m_char[i];   //保持不變  }  else if(' ' == m_char[i]){//如果是空格  result[pos++] = '+';  }  else {//如果是其他字元  BYTE temp = Int_to_Hex((BYTE) m_char[i]);  result[pos++] = '%';  result[pos++] = Int_to_Hex((BYTE)m_char[i] >> 4);    result[pos++] = Int_to_Hex((BYTE)m_char[i] % 16);    }  }IsAnsi = IsAnsiTemp ? ToAnsi() : ToUtf_8();//恢複原來的編碼result[pos++] = '\0';return result;  }/**@目的:將字串用Urlcode解碼*@參數:無*@傳回值: char* 解碼後的字串(格式取決於字串本身的格式)*/char* UrlDecode(){FlushString();char* result = NULL;  size_t nLen = 0;StringCchLengthA(m_char, MAX_COUNT, &nLen);size_t pos = 0;    //結果字串的長度標記  try{result = new char[(nLen+1)*sizeof(wchar_t)];ZeroMemory(result, sizeof(result));}catch(std::bad_alloc){delete []result;result = NULL;return result;}for(size_t i = 0; i < nLen; i++){  if('%' == m_char[i]){ //判斷是否為漢字BYTE cha;cha = Hex_to_Int(m_char[i+1])<<4;cha |= Hex_to_Int(m_char[i+2]);result[pos++] = (char)cha;   i += 2;}  else if('+' == m_char[i]){//如果是空格  result[pos++] = ' ';  }  else {//如果是其他字元  result[pos++] = m_char[i]; //保持不變  }  }result[pos++] = '\0';return result;  }/**@目的:將字串格式化(char*)*@參數:char* Format  格式化字串*@參數:...  參數列表*@傳回值: int 格式化參數的個數, -1表示失敗*/int Format(char* Format, ...){Last_Style = Style_Char;va_list argList = NULL;size_t nLen = 0;va_start(argList, Format);nLen = _vsprintf_p(NULL, 0, Format, argList);try{m_char = new char[nLen+1];_vsprintf_p(m_char, nLen + 1, Format, argList);return FlushString();}catch(std::bad_alloc){delete []m_char;m_char = NULL;return -1;}}/**@目的:將字串格式化(wchar_t*)*@參數:wchar_t* Format  格式化字串*@參數:...  參數列表*@傳回值: int 格式化參數的個數, -1表示失敗*/int Format(wchar_t* Format, ...){Last_Style = Style_WChar;va_list argList = NULL;size_t nLen = 0;va_start(argList, Format);nLen = _vswprintf_p(NULL, 0, Format, argList);try{m_wchar = new wchar_t[nLen+1];_vswprintf_p(m_wchar, nLen + 1, Format, argList);return FlushString();}catch(std::bad_alloc){delete []m_wchar;m_wchar = NULL;return -1;}}public://==運算子多載bool operator == (const char* obj){return 0 == strncmp(m_char, obj, MAX_COUNT) ? true : false;}bool operator == (const wchar_t* obj){return CSTR_EQUAL == CompareStringOrdinal(m_wchar, -1, obj, -1, false) ? true : false;}bool operator == (CYkString &obj){return CSTR_EQUAL == CompareStringOrdinal(m_wchar, -1, obj.asWchar_str(), -1, false) ? true : false;}//=運算子多載CYkString& operator = (const char* obj){Last_Style = Style_Char;if(*this == obj){return *this;}size_t nLen1 = GetLength()*sizeof(wchar_t);size_t nLen2 = 0;StringCchLengthA(obj, MAX_COUNT, &nLen2);nLen2 += 1;if(nLen1 >= nLen2){StringCchCopyA(m_char, nLen1, obj);}else{char *strTemp = NULL;__try{if(NULL == (strTemp = new char[nLen2])){__leave;}if(S_OK != StringCchCopyA(strTemp, nLen2, obj)){__leave;}delete m_char;m_char = NULL;if(NULL == (m_char = new char[nLen2])){__leave;}if(S_OK != StringCchCopyA(m_char, nLen2, strTemp)){__leave;}}__finally{if(NULL != strTemp){delete []strTemp;strTemp = NULL;FlushString();}}}return *this;}CYkString& operator = (const wchar_t* obj){Last_Style = Style_WChar;if(*this == obj){return *this;}size_t nLen1 = GetLength()*sizeof(wchar_t);size_t nLen2 = 0;StringCchLengthW(obj, MAX_COUNT, &nLen2);nLen2 *= sizeof(wchar_t);if(nLen1 >= nLen2){StringCchCopyW(m_wchar, nLen1, obj);}else{wchar_t *strTemp = NULL;__try{if(NULL == (strTemp = new wchar_t[nLen2])){__leave;}if(S_OK != StringCchCopyW(strTemp, nLen2, obj)){__leave;}delete []m_wchar;m_wchar = NULL;if(NULL == (m_wchar = new wchar_t[nLen2])){__leave;}if(S_OK != StringCchCopyW(m_wchar, nLen2, strTemp)){__leave;}}__finally{if(NULL != strTemp){delete []strTemp;strTemp = NULL;FlushString();}}}return *this;}CYkString& operator = (CYkString &obj){return *this = obj.asWchar_str();}//+=運算子多載CYkString& operator += (const char* obj) {Last_Style = Style_Char;size_t nLen1 = GetLength()*sizeof(wchar_t) + 1;size_t nLen2 = 0;StringCchLengthA(obj, MAX_COUNT, &nLen2);nLen2 += 1;char *strTemp = NULL;__try{if(NULL == (strTemp = new char[nLen1])){__leave;}if(S_OK != StringCchCopyA(strTemp, nLen1, m_char)){__leave;}delete []m_wchar;m_wchar = NULL;if(NULL == (m_char = new char[nLen1+nLen2])){__leave;}if(S_OK != StringCchCopyA(m_char, nLen1, strTemp)){__leave;}if(S_OK != StringCchCatA(m_char, nLen1+nLen2, obj)){__leave;}}__finally{if(NULL != strTemp){delete []strTemp;strTemp = NULL;FlushString();}}return *this;}CYkString& operator += (const wchar_t* obj) {Last_Style = Style_WChar;size_t nLen1 = GetLength()*sizeof(wchar_t);size_t nLen2 = 0;StringCchLengthW(obj, MAX_COUNT, &nLen2);nLen2 *= sizeof(wchar_t);wchar_t *strTemp = NULL;__try{if(NULL == (strTemp = new wchar_t[nLen1])){__leave;}if(S_OK != StringCchCopyW(strTemp, nLen1, m_wchar)){__leave;}delete []m_wchar;m_wchar = NULL;if(NULL == (m_wchar = new wchar_t[nLen1+nLen2])){__leave;}if(S_OK != StringCchCopyW(m_wchar, nLen1, strTemp)){__leave;}if(S_OK != StringCchCatW(m_wchar, nLen1+nLen2, obj)){__leave;}}__finally{if(NULL != strTemp){delete []strTemp;strTemp = NULL;FlushString();}}return *this;}CYkString& operator += (CYkString &obj) {return *this += obj.asWchar_str();}protected:char* m_char;//內部字串 char*   窄位元組類型wchar_t* m_wchar;//內部字串 wchar* 寬位元組類型private:enum LASTCHANGE{Style_Char= 1,Style_WChar= 2};//最後改變的資料類型bool IsAnsi;//字串是否是Ansi編碼格式int Last_Style;//最後改變的資料類型標記};#endif // !__YKSTRING



自己編寫的Windows字串類 封裝字串格式轉換和常用操作 方便使用

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.