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