typedef char CHAR
typedef wchar_t WCHAR
typedef CAHR *PCHAR
typedef CHAR *PSTR
typedef CONST CHAR *PCSTR
typedf WCHAR *PWCHAR
typedf WCHAR *PWCHAR
typedef WCHAR *PWSTR
typedef CONST WCHAR *PCWSTR
#ifdef UNICODE
typedef WCHAR TCHAR ,*PTCHAR,PTSTR
typedef CONST WCHAR *PCTSTR
#define _TEXT(quote) quote
#else
typedef CHAR TCHAR ,*PTCHAR,PTSTR;
typedef CONST CHAR *PCTSTR
#define _TEXT(quote) quote
#endif
#define TEXT(quote) _TEXT(quote)
C运行库中的Unicode函数和ANSI函数
_tcslen :strlen--wcslen ---------返回字符串长度
_countof用啦计算啊一个静态分配的数组中的元素的个数
sizeof用来计算字节数
eg
#include <Windowsx.h>
#include <tchar.h>
#include <Windows.h>
#include <errno.h>
int WINAPI _tWinMain(HINSTANCE hinsttExe ,HINSTANCE ,PTSTR szCmdLine ,int )
{
TCHAR szBefore[5] = {L'B',L'B',L'B',L'B',L'\0'};
TCHAR szBuffer[10] = {L'-',L'-',L'-',L'-',L'-',L'-',L'-',L'-',L'-',L'\0'};
TCHAR szAfter[5] = {L'A',L'A',L'A',L'A',L'\0'};
errno_t resulr = _tcscpy_s(szBuffer,_countof(szBuffer),L"0123456789");
return 0;
}
这个函数会造成溢出。下面是改进,但是还是会少一位。下面这个函数有截断作用。可以防止溢出
#include <Windowsx.h>
#include <tchar.h>
#include <Windows.h>
#include <errno.h>
#include <strsafe.h>
int WINAPI _tWinMain(HINSTANCE hinsttExe ,HINSTANCE ,PTSTR szCmdLine ,int )
{
TCHAR szBefore[5] = {L'B',L'B',L'B',L'B',L'\0'};
TCHAR szBuffer[10] = {L'-',L'-',L'-',L'-',L'-',L'-',L'-',L'-',L'-',L'\0'};
TCHAR szAfter[5] = {L'A',L'A',L'A',L'A',L'\0'};
errno_t resulr = StringCchCopy(szBuffer,_countof(szBuffer),L"0123456789");
return 0;
}
windows字符串函数:
CompareString 函数:
eg:
---------------------------------------------------------------------------------------------------------------------
#include <Windowsx.h>
#include <Windows.h>
#include <tchar.h>
#include <Shlwapi.h>
int WINAPI _tWinMain(HINSTANCE hinsttExe ,HINSTANCE ,PTSTR szCmdLine ,int )
{
TCHAR val[] = L"xiaopao";
TCHAR val2[] = L"xiao";
LCID hcid ;
hcid = GetThreadLocale();
int k ;
k = CompareString(hcid,NORM_IGNORECASE,val,_tcslen(val),val2,_tcslen(val2));
if (k == 0 )
{
MessageBox(NULL,L"函数调用失败",L"Compare",MB_OK);
}
if (k == 1)
{
MessageBox(NULL,L"string1 < string2",L"Compare",MB_OK);
}
if(k == 2)
{
MessageBox(NULL,L"string1 = string2",L"Compare",MB_OK);
}
if ( k == 3 )
MessageBox(NULL,L"string1 >string2",L"Compare",MB_OK);
return 0;
}
---------------------------------------------------------------------------------------------------------------------
科普:
为什么要用UNICODE
1:UNICODE有利于应用程序的本地化
2:使用Unicode,只需发布一个二进制(.exe或DLL)文件,就可以支持所有语言
3:Unicode提升了应用程序的效率,因为代码执行速度更快,占用内存更少。Windows内部的一切工作都是使用Unicode字符和Unicode字符串,所以,假如我们坚持传入ANSI字符或字符串,Windows就会被迫分配内存,并将ANSI字符或字符串转换为等价的Unicode
4:使用Unicode,应用程序可以轻松调用所有尚未被弃用的Windows函数,因为一些windows函数提供的版本只能处理unicode字符和字符串
5:应用程序很容易与COM集成
6:应用程序很容易与.NET Framework集成
7:能保证应用程序的代码能够轻松操作我们自己的资源。
推荐的字符和字符串处理方式:
1:开始将文本字符串想象为字符的数组,而不是char或字节的数组
2:用通用数据类型(TCAHR/PTSTR)来表示文本字符和字符串
3:用明确的数据类型(如BYTE/PBYTE)来表示字节 字节、字节指针和数据缓冲区
4:用TEXT或_T宏来表示字面量字符和字符串,但为了保持一致性和更好的可读性,避免两者的混用
5:执行全局替换(PTSTR替换PSTR)
6:避免使用printf系列函数 应使用MultiByteToWideChar和WideCharToMultiByte
7:_countof()-->sizeof() malloc(nCharacters*sizeof(TCHAR)) ----->malloc(nCharacters)
8:UNICODE与_UNICODE符号要么不定义,要么同时定义
字符串处理函数应该遵循的基本准则:
1:始终使用安全的字符串处理函数,eg后缀为_s的函数,或者是前缀为StringCch的函数
2:不要使用不安全的C运行库字符串处理函数,一般情况下,如果一个缓冲区处理函数的参数中不包括目标缓冲区的长度,那么我们就应该避免使用这样的函数,同时还应避免自己实现这样的函数
3:利用/GS和/RTCs编译器标志来自动检测缓冲区溢出
4:不要用Kernel32方法进行字符串处理
5:字符串比较CompareString CompareStringOrdinal
多字节字符转换为宽字节字符
函数:
int MultiByteToWideChar(
UINT CodePage, //
CP_ACP代码页就实现了ANSI与Unicode之间的转换CP_UTF8代码页就实现了UTF-8与Unicode之间的转换 DWORD dwFlags, //一般为0
LPCSTR lpMultiByteStr, //指定要传的字符串
int cchMultiByte, //字符串长度,-1时自己计算长度
LPWSTR lpWideCharStr, //目的字符串
int cchWideChar //目的字符串长度
);
eg:
---------------------------------------------------------------------------------------------------------------------
#include <Windowsx.h>
#include <tchar.h>
#include <Shlwapi.h>
int WINAPI _tWinMain(HINSTANCE hinsttExe ,HINSTANCE ,PTSTR szCmdLine ,int )
{
char val[]="xiaopao";
int k ;
wchar_t * val2 ;
k = MultiByteToWideChar(CP_ACP,0,val,-1,NULL,0); //分配一块足以容纳转换后的Unicode字符串的内存
val2 = new wchar_t[k*sizeof(wchar_t)+1];
MultiByteToWideChar(CP_ACP,0,val,-1,val2,k);
MessageBox(NULL,val2,L"Hello",MB_OK);
return 0;
}
---------------------------------------------------------------------------------------------------------------------
宽字节字符转换为多字节字符
int WideCharToMultiByte(
UINT CodePage,
DWORD dwFlags,
LPWSTR lpWideCharStr,
int cchWideChar,
LPCSTR lpMultiByteStr,
int cchMultiByte,
LPCSTR lpDefaultChar,
PBOOL pfUsedDefaultChar
);
---------------------------------------------------------------------------------------------------------------------
#include <Windowsx.h>
#include <tchar.h>
#include <Shlwapi.h>
int WINAPI _tWinMain(HINSTANCE hinsttExe ,HINSTANCE ,PTSTR szCmdLine ,int )
{
TCHAR val[]=L"xiaopao";
int k ;
char * val2 ;
TCHAR val3[20];
k = WideCharToMultiByte(CP_ACP,0,val,-1,NULL,0,NULL,NULL); //分配一块足以容纳转换后的Unicode字符串的内存
val2 = new char[k+1];
memset((void*)val2,0,sizeof(char)*(k+1));
WideCharToMultiByte(CP_ACP,0,val,-1,val2,k,NULL,NULL);
return 0;
}
---------------------------------------------------------------------------------------------------------------------
字符串的逆转---有中变量
---------------------------------------------------------------------------------------------------------------------
#include <Windowsx.h>
#include <tchar.h>
#include <Shlwapi.h>
PWSTR StringReverseW(PWSTR pWideCharStr ,DWORD cchLength );
int WINAPI _tWinMain(HINSTANCE hinsttExe ,HINSTANCE ,PTSTR szCmdLine ,int )
{
PWSTR val = L"xiaopao";
int k = 0 ;
k =wcslen(val);
StringReverseW(val,k);
return 0;
}
PWSTR StringReverseW(PWSTR pWideCharStr, DWORD cchLength)
{
PWSTR pEndOfStr = pWideCharStr + wcsnlen_s(pWideCharStr, cchLength) - 1;
PWSTR pResult = (WCHAR*)malloc(sizeof(WCHAR));
WCHAR * p=pResult;
wchar_t cCharT;
int i = 0;
int k = wcslen(pResult);
while (cchLength)
{
pEndOfStr--;
cchLength--;
cCharT = *pEndOfStr;
*p = cCharT;
p++;
}
MessageBox(NULL, pResult, L"Hello", MB_OK);
return pResult;
}
---------------------------------------------------------------------------------------------------------------------
字符串逆转--无中间变量
---------------------------------------------------------------------------------------------------------------------
#include <Windowsx.h>
#include <tchar.h>
#include <Shlwapi.h>
PWSTR StringReverseW(PWSTR pWideCharStr ,DWORD cchLength );
int WINAPI _tWinMain(HINSTANCE hinsttExe ,HINSTANCE ,PTSTR szCmdLine ,int )
{
PWSTR val = L"xiaopao";
int k = 0 ;
k =wcslen(val);
StringReverseW(val,k);
return 0;
}
PWSTR StringReverseW(PWSTR pWideCharStr, DWORD cchLength)
{
PWSTR pEndOfStr = pWideCharStr + wcsnlen_s(pWideCharStr, cchLength) - 1;
PWSTR pResult = (TCHAR*)malloc(cchLength*sizeof(TCHAR));
wchar_t cCharT;
int i = 0;
int k = wcslen(pResult);
while (cchLength)
{
pEndOfStr--;
cchLength--;
cCharT = *pEndOfStr;
*pResult = cCharT;
pResult++;
}
pResult--;
pResult--;
pResult--;
pResult--;
pResult--;
pResult--;
MessageBox(NULL, pResult, L"Hello", MB_OK);
return pResult;
}
---------------------------------------------------------------------------------------------------------------------
多字节字符串的逆转
---------------------------------------------------------------------------------------------------------------------
#include <Windowsx.h>
#include <tchar.h>
#include <Shlwapi.h>
BOOL StringReverseW(PWSTR pWideCharStr ,DWORD cchLength );
BOOL StringReverseA(PSTR pMultiByteStr, DWORD cchLength);
int WINAPI _tWinMain(HINSTANCE hinsttExe ,HINSTANCE ,PTSTR szCmdLine ,int )
{
PSTR val = "xiaopao";
int k = 0 ;
k =strlen(val);
StringReverseA(val,k);
return 0;
}
BOOL StringReverseW(PWSTR pWideCharStr, DWORD cchLength)
{
PWSTR pEndOfStr = pWideCharStr + wcsnlen_s(pWideCharStr, cchLength) - 1;
PWSTR pResult = (WCHAR*)malloc(sizeof(WCHAR));
WCHAR * p=pResult;
wchar_t cCharT;
int i = 0;
int k = wcslen(pResult);
while (cchLength)
{
pEndOfStr--;
cchLength--;
cCharT = *pEndOfStr;
*p = cCharT;
p++;
}
return TRUE;
}
BOOL StringReverseA(PSTR pMultiByteStr, DWORD cchLength)
{
PWSTR pWideCharStr ;
int nLenOfWideCharStr ;
BOOL fOk = FALSE;
nLenOfWideCharStr =MultiByteToWideChar (CP_ACP,0,pMultiByteStr,cchLength,NULL,0);
pWideCharStr = (PWSTR)HeapAlloc(GetProcessHeap(),0,nLenOfWideCharStr*sizeof(wchar_t));
if (pWideCharStr == NULL)
return NULL;
MultiByteToWideChar (CP_ACP,0,pMultiByteStr,cchLength,pWideCharStr,nLenOfWideCharStr);
fOk = StringReverseW(pWideCharStr,cchLength);
if (fOk)
{
WideCharToMultiByte(CP_ACP,0,pWideCharStr,cchLength,pMultiByteStr,(int)strlen(pMultiByteStr),NULL,NULL);
}
HeapFree(GetProcessHeap(),0,pWideCharStr);
return TRUE;
}
---------------------------------------------------------------------------------------------------------------------
注:HeapAlloc它用来在指定的堆上分配内存,并且分配后的内存不可移动
LPVOID HeapAlloc(
HANDLE hHeap,
DWORD dwFlags,
SIZE_T dwBytes,
);
hHeap
要分配堆的句柄,可以通过HeapCreate()函数或GetProcessHeap()函数获得。
dwFlags
堆分配时的可选参数,其值可以为以下的一种或多种:
值 | 意义 |
---|
HEAP_GENERATE_EXCEPTIONS | 如果分配错误将会抛出异常,而不是返回NULL。异常值可能是STATUS_NO_MEMORY, 表示获得的内存容量不足,或是STATUS_ACCESS_VIOLATION,表示存取不合法。 |
HEAP_NO_SERIALIZE | 不使用连续存取。 |
HEAP_ZERO_MEMORY | 将分配的内存全部清零。 |
dwBytes
要分配堆的字节数。