对消息的处理中我们经常需要将WPARAM或LPARAM等32位数据(DWORD)分解成两个16位数据(WORD),例如:
LPARAM lParam;
WORD loValue = LOWORD(lParam); //取低16位
WORD hiValue = HIWORD(lParam); //取高16位
对于16位的数据(WORD)我们可以用同样的方法分解成高低两个8位数据(BYTE),例如:
WORD wValue;
BYTE loValue = LOBYTE(wValue); //取低8位
BYTE hiValue = HIBYTE(wValue); //取高8位
如何将CString类型的变量赋给char*类型的变量
1、GetBuffer函数:
使用CString::GetBuffer函数。
char *p;
CString str="hello";
p=str.GetBuffer(str.GetLength());
str.ReleaseBuffer();
将CString转换成char * 时
CString str("aaaaaaa");
strcpy(str.GetBuffer(10),"aa");
str.ReleaseBuffer();
当我们需要字符数组时调用GetBuffer(int n),其中n为我们需要的字符数组的长度.使用完成后一定要马上调用ReleaseBuffer();
还有很重要的一点就是,在能使用const char *的地方,就不要使用char *
2、memcpy:
CString mCS=_T("cxl");
char mch[20];
memcpy(mch,mCS,20);
3、用LPCTSTR强制转换: 尽量不使用
char *ch;
CString str;
ch=(LPSTR)(LPCTSTR)str;
CString str = "good";
char *tmp;
sprintf(tmp,"%s",(LPTSTR)(LPCTSTR)str);
4、
CString Msg;
Msg=Msg+"abc";
LPTSTR lpsz;
lpsz = new TCHAR[Msg.GetLength()+1];
_tcscpy(lpsz, Msg);
char * psz;
strcpy(psz,lpsz);
CString类向const char *转换
char a[100];
CString str("aaaaaa");
strncpy(a,(LPCTSTR)str,sizeof(a));
或者如下:
strncpy(a,str,sizeof(a));
以上两种用法都是正确地. 因为strncpy的第二个参数类型为const char
*.所以编译器会自动将CString类转换成const char *.
CString转LPCTSTR (const char *)
CString cStr;
const char *lpctStr=(LPCTSTR)cStr;
LPCTSTR转CString
LPCTSTR lpctStr;
CString cStr=lpctStr;
将char*类型的变量赋给CString型的变量
可以直接赋值,如:
CString myString = "This is a test";
也可以利用构造函数,如:
CString s1("Tom");
将CString类型的变量赋给char []类型(字符串)的变量
1、sprintf()函数
CString str = "good";
char tmp[200] ;
sprintf(tmp, "%s",(LPCSTR)str);
(LPCSTR)str这种强制转换相当于(LPTSTR)(LPCTSTR)str
CString类的变量需要转换为(char*)的时,使用(LPTSTR)(LPCTSTR)str
然而,LPCTSTR是const char
*,也就是说,得到的字符串是不可写的!将其强制转换成LPTSTR去掉const,是极为危险的!
一不留神就会完蛋!要得到char
*,应该用GetBuffer()或GetBufferSetLength(),用完后再调用ReleaseBuffer()。
2、strcpy()函数
CString str;
char c[256];
strcpy(c, str);
char mychar[1024];
CString source="Hello";
strcpy((char*)&mychar,(LPCTSTR)source);
关于CString的使用
1、指定 CString 形参
对于大多数需要字符串参数的函数,最好将函数原型中的形参指定为一个指向字符 (LPCTSTR)
而非 CString 的 const 指针。
当将形参指定为指向字符的 const 指针时,可将指针传递到 TCHAR 数组(如字符串 ["hi
there"])或传递到 CString 对象。
CString 对象将自动转换成 LPCTSTR。任何能够使用 LPCTSTR 的地方也能够使用
CString 对象。
2、如果某个形参将不会被修改,则也将该参数指定为常数字符串引用(即 const
CString&)。如果函数要修改该字符串,
则删除 const 修饰符。如果需要默认为空值,则将其初始化为空字符串 [""],如下所示:
void AddCustomer( const CString& name, const
CString& address, const CString& comment = "" );
3、对于大多数函数结果,按值返回 CString 对象即可。
串的基本运算
对于串的基本运算,很多高级语言均提供了相应的运算符或标准的库函数来实现。
为叙述方便,先定义几个相关的变量:
char
s1[20]="dir/bin/appl",s2[20]="file.asm",s3[30],*p;
int result;
下面以C语言中串运算介绍串的基本运算
1、求串长
int strlen(char *s); //求串s的长度
【例】printf("%d",strlen(s1)); //输出s1的串长12
2、串复制
char *strcpy(char
*to,*from);//将from串复制到to串中,并返回to开始处指针
【例】strcpy(s3,s1); //s3="dir/bin/appl",s1串不变
3、联接
char *strcat(char *to,char
*from);//将from串复制到to串的末尾,
//并返回to串开始处的指针
【例】strcat(s3,"/"); //s3="dir/bin/appl/"
strcat(s3,s2);
//s3="dir/bin/appl/file.asm"
4、串比较
int strcmp(char *s1,char *s2);//比较s1和s2的大小,
//当s1<s2、s1>s2和s1=s2时,分别返回小于0、大于0和等于0的值
【例】result=strcmp("baker","Baker");
//result>0
result=strcmp("12","12");
//result=0
result=strcmp("Joe","joseph")
//result<0
5、字符定位
char *strchr(char *s,char
c);//找c在字符串s中第一次出现的位置,
//若找到,则返回该位置,否则返回NULL
【例】p=strchr(s2,'.'); //p指向"file"之后的位置
if(p) strcpy(p,".cpp"); //s2="file.cpp"
注意:
①上述操作是最基本的,其中后
4个操作还有变种形式:strncpy,strncath和strnchr。
②其它的串操作见C的<string.h>。在不同的高级语言中,对串运算的种类及符号都不尽相同
③其余的串操作一般可由这些基本操作组合而成
【例】求子串的操作可如下实现:
void substr(char *sub,char *s,int pos,int
len){
//s和sub是字符数组,用sub返回串s的第pos个字符起长度为len的子串
//其中0<=pos<=strlen(s)-1,且数组sub至少可容纳len+1个字符。
if (pos<0||pos>strlen(s)-1||len<0)
Error("parameter error!");
strncpy(sub,&s[pos],len);
//从s[pos]起复制至多len个字符到sub
CString 型转化成 int 型
把 CString 类型的数据转化成整数类型最简单的方法就是使用标准的字符串到整数转换例程。
虽然通常你怀疑使用_atoi()函数是一个好的选择,它也很少会是一个正确的选择。如果你准备使用 Unicode 字符,你应该用_ttoi(),它在 ANSI 编码系统中被编译成_atoi(),而在 Unicode
编码系统中编译成_wtoi()。你也可以考虑使用_tcstoul()或者_tcstol(),它们都能把字符串转化成任意进制的长整数(如二进制、八进制、十进制或十六进制),不同点在于前者转化后的数据是无符号的(unsigned),而后者相反。看下面的例子
CString hex = _T("FAB");CString decimal = _T("4011");ASSERT(_tcstoul(hex, 0, 16) == _ttoi(decimal));
CString格式化字符串
与其用 sprintf() 函数或 wsprintf() 函数来格式化一个字符串,还不如用 CString
对象的Format()方法:
CString s;s.Format(_T("The total is %d"), total); 用这种方法的好处是你不用担心用来存放格式化后数据的缓冲区是否足够大,这些工作由CString类替你完成。
格式化是一种把其它不是字符串类型的数据转化为CString类型的最常用技巧,比如,把一个整数转化成CString类型,可用如下方法:
CString s;s.Format(_T("%d"), total);
在EVC下,我将CString转为Char *的时候可以这样写
#include <atlconv.h>
... USES_CONVERSION;
CString str="Cstring";
char *p;
p=(char*)W2A((LPCTSTR)str);
或者这样写
CString strDemo;
char AnsiString[MAX_PATH] = { 0 };
wcstombs(AnsiString, (LPTSTR)(LPCTSTR)strDemo, strDemo.GetLength());
或者这样写
char* = (LPSTR)(LPCTSTR)CString;
const char* = (LPCSTR)(LPCTSTR)CString;
或者这样写
CString strFilePath;
char FilePath[256];
memset( FilePath, 0, 256 );
strFilePath = "hello world";
WideCharToMultiByte( CP_ACP, 0, strFilePath, -1, FilePath, 256,
NULL, NULL);
...
或者这样写
首先获得char缓冲区大小,然后再通过WideCharToMultiByte转换
CString strConvert;
char pchBuffer;
int iSize;
iSize = WideCharToMultiByte(CP_ACP,0, strFilePath.GetBuffer(0), -1,
NULL, 0, NULL, NULL);
pchBuffer = new char[iSize*2 + 1];
if(pchBuffer != NULL)
{
memset(pchBuffer , 0 , (iSize*2 + 1)*sizeof(char));
}
WideCharToMultiByte(CP_ACP,0, strFilePath.GetBuffer(0), -1,
pchBuffer, (iSize*2 + 1), NULL, NULL);
浅谈EVC中文字符串操作
EVC在某种意义上说,相当于VC的一个子集。因为大多EVC有的功能,VC也具备,而VC有的功能,EVC则不一定拥有。在VC中,操作字符串很方便,因为WINDOWS的字处理能力实在是很强大,它支持多种字符集。我们随便使用一个CString str=“你好”,就要以输入我们想要的中文字符串。在EVC中这种情况有所改变,因为WINCE的字处理能力不够强大,它在处理汉字里统一将它示为UNICODE编码,所以我们在EVC中片理中文字符串时需要用到UNICODE编码。下面结合WINDOWS 下VC字符串的处理,对比一下EVC中文字符串的片理方法。
一、中文字符串定义
1、在VC中我们如果定义一个中文字符串,可以使用CString str=“你好”或LPCTSTR str=“你好”。
2、在EVC中我们如果想定义一个中文字符串,可以使用如下方法:CString str=_T(“你好”)或者LPCTSTR str=“你好”,这里LPCTSTR在EVC里就是表示UNICODE字符串。值得注意的是_T()宏中,括号中只能填写常量,不能填定变量。
二、字符串操作
1、在VC中我们想拷贝字符串,可以作如下操作:
char s[20];
CString str=“你好”;
strcpy(s,str);
在EVC中则不能这样做,首先定义中文数组应该用双字节指针wchar_t,而拷贝函数也不能用strcpy,而应该用:wchar_t * wcscpy(wchar_t * wDest,wchar_t wSource);函数,操作如下:
wchar_t s[20];
CString str=“你好”;
wcscpy(s,(LPCTSTR)str); //前面没有转成UNICODE编码,所以这里需要强制转换
2、在VC中我们想在一个字符串中查找某个子串,只需要作下面的操作:
CString str=“你是一个好学生”;
str.Find(“学生”);
在EVC中不能这样做,因为中文字符串为UNICODE编码,我们必需在查找函数的参数里作如下修改:
str.Find(_T(“学生”));
以上是我在用EVC写应用程序时操作中文字符串的一些积累,以文记之,以备不时之需。
单宽字节互换的程序,估计以后还用得着。
void MyWideCharToMultiByte(WCHAR* wchars,CHAR* schars,int scharsLen)
{
memset(schars,0,scharsLen);
CString m_snd = wchars;
int len = m_snd.GetLength();
CString tmpstr(m_snd); //复制要发送的字符串
int multibytelen=WideCharToMultiByte( //计算从Unicode转换到Ansi后需要的字节数
CP_ACP, //根据ANSI code page转换
WC_COMPOSITECHECK | WC_DEFAULTCHAR, //转换出错用缺省字符代替
(LPCWSTR)tmpstr.GetBuffer(len), //要转换的字符串地址
len, //要转换的个数
0, //转换后字符串放置的地址
0, //最多转换字符的个数,为0表示返回转换Unicode后需要多少个字节
0, //缺省的字符:"\0"
0 //缺省的设置
);
WideCharToMultiByte( //转换Unicode到Ansi
CP_ACP,
WC_COMPOSITECHECK | WC_DEFAULTCHAR,
(LPCWSTR)tmpstr.GetBuffer(len),
len,
(char *)schars, //转换到缓冲区中
scharsLen, //最多个字节
0,
0
);
}
//程序接收到的字符串最后保存到CString tmpstr中.
//接收函数片断
void MyMultiByteToWideChar(char* schars,CString &wstr)
{
// TODO: Add your specialized code here and/or call the base class
// char * p = "abcdefg我是谁hijk";
int widecharlen=MultiByteToWideChar( //计算从Ansi转换到Unicode后需要的字节数
CP_ACP,
MB_COMPOSITE,
(char*)schars, //要转换的Ansi字符串
-1, //自动计算长度
0,
0
);
CString tmpstr;
tmpstr.GetBuffer(widecharlen); //为转换后保存Unicode字符串分配内存
MultiByteToWideChar( //从Ansi转换到Unicode字符
CP_ACP,
MB_COMPOSITE,
(char*)schars,
-1,
(LPWSTR)tmpstr.GetBuffer(widecharlen), //转换到tmpstr
widecharlen //最多转换widecharlen个Unicode字符
);
wstr = tmpstr;
}
void TestFunction()
{
TCHAR abc[]=_T("ab我们的家ab");
char b[15];
MyWideCharToMultiByte(abc,b,sizeof(b));
// char c[]="ab如果cd就好了!abcdefg";
CString str;
MyMultiByteToWideChar(b,str);
MyWideCharToMultiByte((LPWSTR)str.GetBuffer(0),b,sizeof(b));
}