1. 程式人生 > >ANSI和UNICODE字串處理常用函式

ANSI和UNICODE字串處理常用函式

ANSI和UNICODE字串處理函式

在windows中ANSI和UNICODE字串操作分別提供了相應的函式,也提供了一套相容兩者的函式。比如:
#ifdef  UNICODE  
    #define _tcscpy     wcscpy 
#else 
    #define _tcscpy     strcpy 
#endif

字串處理函式常用函式對照

ANSI UNICODE 通用 說明
資料型別
(char.h) (wchar.h) (tchar.h)
char wchar_t TCHAR
char * wchar_t * TCHAR*
LPSTR LPWSTR LPTSTR
LPCSTR LPCWSTR LPCTSTR
字串轉換
atoi _wtoi _ttoi 把字串轉換成整數(int)
atol _wtol _ttol 把字串轉換成長整型數(long)
atof _wtof _tstof 把字串轉換成浮點數(double)
itoa _itow _itot 將任意型別的數字轉換為字串
字串操作
strlen wcslen _tcslen 獲得字串的數目
strcpy wcscpy _tcscpy 拷貝字串
strncpy wcsncpy _tcsncpy 類似於strcpy/wcscpy,同時指定拷貝的數目
strcmp wcscmp _tcscmp 比較兩個字串
strncmp wcsncmp _tcsncmp 類似於strcmp/wcscmp,同時指定比較字元字串的數目
strcat wcscat _tcscat 把一個字串接到另一個字串的尾部
strncat wcsncat _tcsnccat 類似於strcat/wcscat,而且指定粘接字串的粘接長度.
strchr wcschr _tcschr 查詢子字串的第一個位置
strrchr wcsrchr _tcsrchr 從尾部開始查詢子字串出現的第一個位置
strpbrk wcspbrk _tcspbrk 從一字元字串中查詢另一字串中任何一個字元第一次出現的位置
strstr wcsstr/wcswcs _tcsstr 在一字串中查詢另一字串第一次出現的位置
strcspn wcscspn _tcscspn 返回不包含第二個字串的的初始數目
strspn wcsspn _tcsspn 返回包含第二個字串的初始數目
strtok wcstok _tcstok 根據標示符把字串分解成一系列字串
wcswidth 獲得寬字串的寬度
wcwidth 獲得寬字元的寬度
字串測試
isascii iswascii _istascii 測試字元是否為ASCII 碼字元, 也就是判斷c 的範圍是否在0 到127 之間
isalnum iswalnum _istalnum 測試字元是否為數字或字母
isalpha iswalpha _istalpha 測試字元是否是字母
iscntrl iswcntrl _istcntrl 測試字元是否是控制符
isdigit iswdigit _istdigit 測試字元是否為數字
isgraph iswgraph _istgraph 測試字元是否是可見字元
islower iswlower _istlower 測試字元是否是小寫字元
isprint iswprint _istprint 測試字元是否是可列印字元
ispunct iswpunct _istpunct 測試字元是否是標點符號
isspace iswspace _istspace 測試字元是否是空白符號
isupper iswupper _istupper 測試字元是否是大寫字元
isxdigit iswxdigit _istxdigit 測試字元是否是十六進位制的數字
大小寫轉換
tolower towlower _totlower 把字元轉換為小寫
toupper towupper _totupper 把字元轉換為大寫
字元比較
strcoll wcscoll _tcscoll 比較字串
日期和時間轉換
strftime wcsftime _tcsftime 根據指定的字串格式和locale設定格式化日期和時間
strptime 根據指定格式把字串轉換為時間值, 是strftime的反過程
列印和掃描字串
printf wprintf _tprintf 使用vararg參量的格式化輸出到標準輸出
fprintf fwprintf _ftprintf 使用vararg參量的格式化輸出
scanf wscanf _tscanf 從標準輸入的格式化讀入
fscanf fwscanf _ftscanf 格式化讀入
sprintf swprintf _stprintf 根據vararg參量表格式化成字串
sscanf swscanf _stscanf 以字串作格式化讀入
vfprintf vfwprintf _vftprintf 使用stdarg參量表格式化輸出到檔案
vprintf 使用stdarg參量表格式化輸出到標準輸出
vsprintf vswprintf _vstprintf 格式化stdarg參量表並寫到字串
sprintf_s swprintf_s _stprintf_s 格式化字串
數字轉換
strtod wcstod _tcstod 把字串的初始部分轉換為雙精度浮點數
strtol wcstol _tcstol 把字串的初始部分轉換為長整數
strtoul wcstoul _tcstoul 把字串的初始部分轉換為無符號長整數
_strtoi64 _wcstoi64 _tcstoi64
輸入和輸出
fgetc fgetwc _fgettc 從流中讀入一個字元並轉換為寬字元
fgets fgetws _fgetts 從流中讀入一個字串並轉換為寬字串
fputc fputwc _fputtc 把寬字元轉換為多位元組字元並且輸出到標準輸出
fputs fputws _fputts 把寬字串轉換為多位元組字元並且輸出到標準輸出串
getc getwc _gettc 從標準輸入中讀取字元, 並且轉換為寬字元
getchar getwchar _gettchar 從標準輸入中讀取字元
putc putwc _puttc 標準輸出
putchar putwchar _puttchar 標準輸出
ungetc ungetwc _ungettc 把一個字元放回到輸入流中

多位元組和寬位元組字串的轉換
使用MultiByteToWideChar函式和WideCharToMultiByte函式可以實現多位元組寬位元組之間的轉換。ATL的一個很好的字串的轉換巨集:A2W和W2A,使用起來更加簡單。
一、MultiByteToWideChar和WideCharToMultiByte函式

#include <string> 
#include <windows.h> 
using namespace std; 
//Converting a WChar string to a Ansi string 
std::string WChar2Ansi(LPCWSTR pwszSrc) 
{ 
         int nLen = WideCharToMultiByte(CP_ACP, 0, pwszSrc, -1, NULL, 0, NULL, NULL); 
         if (nLen<= 0) return std::string(""); 
         char* pszDst = new char[nLen]; 
         if (NULL == pszDst) return std::string(""); 
         WideCharToMultiByte(CP_ACP, 0, pwszSrc, -1, pszDst, nLen, NULL, NULL); 
         pszDst[nLen -1] = 0; 
         std::string strTemp(pszDst); 
         delete [] pszDst; 
         return strTemp; 
}
string ws2s(wstring& inputws) 
{ 
        return WChar2Ansi(inputws.c_str()); 
}
//Converting a Ansi string to WChar string 
std::wstring Ansi2WChar(LPCSTR pszSrc, int nLen) 
{ 
    int nSize = MultiByteToWideChar(CP_ACP, 0, (LPCSTR)pszSrc, nLen, 0, 0); 
    if(nSize <= 0) return NULL; 
         WCHAR *pwszDst = new WCHAR[nSize+1]; 
    if( NULL == pwszDst) return NULL; 
    MultiByteToWideChar(CP_ACP, 0,(LPCSTR)pszSrc, nLen, pwszDst, nSize); 
    pwszDst[nSize] = 0; 
    if( pwszDst[0] == 0xFEFF)                    // skip Oxfeff 
        for(int i = 0; i < nSize; i ++) 
                            pwszDst[i] = pwszDst[i+1]; 
    wstring wcharString(pwszDst); 
         delete pwszDst; 
    return wcharString; 
}
std::wstring s2ws(const string& s) 
{ 
     return Ansi2WChar(s.c_str(),s.size()); 
}

二、MultiByteToWideChar和WideCharToMultiByte函式

std::wstring AsciiToUnicode(const std::string& str)
{
	// 預算-緩衝區中寬位元組的長度  
	int unicodeLen = MultiByteToWideChar(CP_ACP, 0, str.c_str(), -1, nullptr, 0);
	// 給指向緩衝區的指標變數分配記憶體  
	wchar_t *pUnicode = (wchar_t*)malloc(sizeof(wchar_t)*unicodeLen);
	// 開始向緩衝區轉換位元組  
	MultiByteToWideChar(CP_ACP, 0, str.c_str(), -1, pUnicode, unicodeLen);
	std::wstring ret_str = pUnicode;
	free(pUnicode);
	return ret_str;
}

std::string UnicodeToUtf8(const std::wstring& wstr)
{
	// 預算-緩衝區中多位元組的長度  
	int ansiiLen = WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), -1, nullptr, 0, nullptr, nullptr);
	// 給指向緩衝區的指標變數分配記憶體  
	char *pAssii = (char*)malloc(sizeof(char)*ansiiLen);
	// 開始向緩衝區轉換位元組  
	WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), -1, pAssii, ansiiLen, nullptr, nullptr);
	std::string ret_str = pAssii;
	free(pAssii);
	return ret_str;
}

//ANSI轉UTF8
std::string AsciiToUtf8(const std::string& str)
{
	return UnicodeToUtf8(AsciiToUnicode(str));
}

//UTF8轉ANSI
std::string Utf8toAscii(const std::string strUTF8)
{
	std::string  strAnsi = "";
	//獲取轉換為多位元組後需要的緩衝區大小,建立多位元組緩衝區
	UINT nLen = MultiByteToWideChar(CP_UTF8, NULL, strUTF8.c_str(), -1, NULL, NULL);
	WCHAR *wszBuffer = new WCHAR[nLen + 1];
	nLen = MultiByteToWideChar(CP_UTF8, NULL, strUTF8.c_str(), -1, wszBuffer, nLen);
	wszBuffer[nLen] = 0;
	nLen = WideCharToMultiByte(936, NULL, wszBuffer, -1, NULL, NULL, NULL, NULL);
	CHAR *szBuffer = new CHAR[nLen + 1];
	nLen = WideCharToMultiByte(936, NULL, wszBuffer, -1, szBuffer, nLen, NULL, NULL);
	szBuffer[nLen] = 0;
	strAnsi = szBuffer;
	//清理記憶體
	delete[]szBuffer;
	delete[]wszBuffer;
	return strAnsi;
}

三、A2W、W2A、A2T、T2A的使用方法
型別T。如果定義了 _UNICODE,則T表示W;如果定義了 _MBCS,則T表示A
標頭檔案包含
#include <atlbase.h>


(1)A2W的用法:

USES_CONVERSION;   // 只需要呼叫一次,就可以在函式中進行多次轉換
CString tmpStr;  
char*LineChar="fdsfdsa";  
const WCHAR * cLineChar = A2W(LineChar);  
tmpStr=cLineChar;  
//獲取字元個數
wcslen(cLineChar );

(2)W2A的用法:

USES_CONVERSION;  
CString tmpStr;  
WCH LineChar="fdsfdsa";  
const char* cLineChar = A2W(LineChar);  

(3)A2T的用法:

USES_CONVERSION;  
char * pChar="char to cstring";  
CString cTemp=A2T(pChar);  

(4)T2A的用法:

USES_CONVERSION;  
CString cTemp =_T("char to cstring");  
char * pChar=T2A(cTemp.GetBuffer(cTemp.GetLength()));  

四、幾種ANSI和UNICODE的巨集定義
L 在字串前加一個L,如 L”我的字串” 表示將ANSI字串轉換成unicode的字串,就是每個字元佔用兩個位元組。
strlen(L”asd”) = 6;
_T巨集可以把一個引號引起來的字串,根據你的環境設定,使得編譯器會根據編譯目標環境選擇合適的(Unicode還是ANSI)字元處理方式。
TEXT,_TEXT 和_T 一樣的。

std相容字串定義

#ifdef _UNICODE  
#define tstring std::wstring  
#else  
#define tstring std::string  
#endif 

long int strtol(const char *str, char **endptr, int base) 把引數 str 所指向的字串根據給定的 base 轉換為一個長整數(型別為 long int 型),base 必須介於 2 和 36(包含)之間,或者是特殊值 0。

例項:

#include <stdio.h>
#include <stdlib.h>
int main()
{
   char str[30] = "2030300 This is test";
   char *ptr;
   long ret;
   ret = strtol(str, &ptr, 10);
   printf("數字(無符號長整數)是 %ld\n", ret);
   printf("字串部分是 |%s|", ptr);
   return(0);
}

結果:

數字(無符號長整數)是 2030300
字串部分是 | This is test|

開源字元轉換iconv
http://www.gnu.org/software/libiconv/
https://blog.csdn.net/langresser_king/article/details/7459367