鱼C论坛

 找回密码
 立即注册

核心编程--第二章

热度 8已有 1979 次阅读2015-1-5 23:01 |个人分类:windows核心编程

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
要分配堆的字节数。


路过

鸡蛋
8

鲜花

握手

雷人

刚表态过的朋友 (8 人)

评论 (0 个评论)

facelist

您需要登录后才可以评论 登录 | 立即注册

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-4-25 06:39

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

返回顶部