|
# 复杂的宽窄字节数据类型
刚开始学编程的时候我们就接触了char、char*之类的,属于窄字节的,按照刚刚讲的,又多了一个`wchar_t`类型的字符,字符串指针的话就可以是`wchar_t*`类型。但是,在我们平时的编程过程中还会见到很多其他的复杂类型,如下:
- 窄字节:
char、char * , const char *
CHAR、(PCHAR、PSTR、LPSTR)、LPCSTR
- Unicode宽字节:
wchar_t、wchar_t * 、const wchar_t*
WCHAR、(PWCHAR、PWSTR、LPWSTR)、LPCWSTR\
- T通用类型∶
TCHAR、(TCHAR*、PTCHAR、PTSTR、LPTSTR)、LPCTSTR
其中:P代表指针的意思,STR代表字符串的意思,L是长指针的意思,在WIN32平台下可以忽略,C代表const常量的意思,W代表wide宽字节的意思,T大家可以理解为通用类型的意思,
就是可以根据工程中是否定义_UNICODE宏,来判断当前工程的编码类型是宽字节还是窄字节,之后分别定义成不同的类型,比如:TCHAR类型,如果工程中定义了_UNICODE宏,那么就表明工程是宽字节编码,他最终就被定义成wchar_t类型,如果工程中没有定义_UNICODE宏,就表明工程当前是窄字节编码,那么TCHAR 被最终定义成char类型。
其方便性就是修改了工程的编码格式之后不用修改代码,所以还是建议大家在编写程序的时候使用通用类型
# 开发常用函数总结
```c
int _tmain(int argc,TCHAR* argv)
{
char* p_a = "123"; //窄字节
wchar_t* p_b = L"123"; //宽字节
TCHAR* p_t = _T("123"); //通用字节
//----------------------------------求字符串长度
int a_len = strlen(p_a); // 3
int b_len = wcslen(p_b); // 3
int t_len = _tcslen(p_t); //3
//----------------------------------字符串转 int
int i_a = atoi(p_a);
int i_b = _wtoi(p_b);
int i_t = _tstoi(p_t);
//----------------------------------字符串转 double
double d_a = atof(p_a);
double d_b = _wtof(p_b);
double d_t = _tstof(p_t);
//----------------------------------字符串 拷贝
char dest_a[MAX_PATH] = { 0 };
wchar_t dest_b[MAX_PATH] = { 0 };
TCHAR dest_t[MAX_PATH] = { 0 };
strcpy(dest_a, p_a);
wcscpy(dest_b, p_b);
_tcscpy(dest_t,p_t);
//----------------------------------字符串拼接
strcat(dest_a,"123456");
wcscat(dest_b, L"123456");
_tcscat(dest_t, _T("123456"));
//----------------------------------字符串比较
int a_res = strcmp(dest_a, "123123456");
int b_res = wcscmp(dest_b, L"123123456");
int t_res = _tcscmp(dest_t, _T("123123456"));
//----------------------------------字符串 安全拷贝
char dest_safe_a[MAX_PATH] = { 0 };
wchar_t dest_safe_b[MAX_PATH] = { 0 };
TCHAR dest_safe_t[MAX_PATH] = { 0 };
strcpy_s(dest_safe_a, MAX_PATH,"123123456");
wcscpy_s(dest_safe_b, MAX_PATH, L"123123456");
_tcscpy_s(dest_safe_t, MAX_PATH,_T("123123456"));
return 0;
}
```
# 宽窄字节字符串转化
```c
BOOL a2w
(
/*输入参数*/
char* multi_str, /*窄字节字符串*/
/*输出参数*/
wchar_t** w_str /*宽字节字符串*/
)
{
//计算转为宽字节的数量
int need_w_char_count = MultiByteToWideChar(CP_ACP, 0, multi_str, -1, NULL, 0);
if (0 == need_w_char_count)
return FALSE;
//动态开辟内存空间
*w_str = NULL;
*w_str = new wchar_t[need_w_char_count];
wmemset(*w_str, 0, need_w_char_count); //初始化
//执行转换
if (!MultiByteToWideChar(CP_ACP, 0, multi_str, -1, *w_str, need_w_char_count))
return TRUE;
else
return FALSE;
}
int _tmain(int argc,TCHAR* argv)
{
char* p_a = "12345";
wchar_t* p_b = NULL;
a2w(p_a, &p_b);
delete[] p_b;
p_b = NULL;
return 0;
}
```
```c
BOOL w2a
(
/*输入参数*/
wchar_t* w_str, /*宽字节字符串*/
/*输出参数*/
char** multi_str /*窄字节字符串*/
)
{
//计算转为窄字节字符串 数量
int need_multi_count = WideCharToMultiByte(CP_ACP,0, w_str,-1,NULL,0, NULL, FALSE);
if (0 == need_multi_count)
return FALSE;
*multi_str = NULL;
*multi_str = new char[need_multi_count];
memset(*multi_str,0, need_multi_count);
if (WideCharToMultiByte(CP_ACP, 0, w_str, -1, *multi_str, need_multi_count, NULL, FALSE))
return TRUE;
else
return FALSE;
}
int _tmain(int argc,TCHAR* argv)
{
wchar_t* p_w = L"1234567";
char* p_a = NULL;
w2a(p_w, &p_a);
delete[] p_a;
p_a = NULL;
return 0;
}
```
# 更方便的转换
```c
int _tmain(int argc,TCHAR* argv)
{
//不建议使用A2W W2A T2A T2W 之类的宏转换了,在字符串很长的时候就会有问题。
//使用更加安全的CA2W CW2A CT2W CT2A
//宽字节 转为多字节
wchar_t* p_wstr = L"你好123";
CW2A w2aObj(p_wstr);
char* p_mutil_str = (char*)w2aObj;
std::cout << p_mutil_str;
return 0;
}
```
```c
int _tmain(int argc,TCHAR* argv)
{
//不建议使用A2W W2A T2A T2W 之类的宏转换了,在字符串很长的时候就会有问题。
//使用更加安全的CA2W CW2A CT2W CT2A
//多字节 转为宽字节
char* p_mutil_str = "123456";
CA2W w2aObj(p_mutil_str);
wchar_t* p_w_str = (wchar_t*)w2aObj;
return 0;
}
```
```c
int _tmain(int argc,TCHAR* argv)
{
//不建议使用A2W W2A T2A T2W 之类的宏转换了,在字符串很长的时候就会有问题。
//使用更加安全的CA2W CW2A CT2W CT2A
TCHAR p_tstr[] = _T("123456");
CT2A t2AObj(p_tstr);
CT2W t2WObj(p_tstr);
char* p_multi = (char*) t2AObj;
wchar_t* p_w = (wchar_t*) t2WObj;
std::cout << p_multi;
std::wcout << p_w;
return 0;
}
```
# CString来了!
虽然C++STL中的string 实比C语言中的字符串处理方便很多,但是这里我要说,跟成熟的字符串处理还是差很多,起码跟CString来说就差了不少.
比如:
trim操作∶去除掉首尾的不可见字符,比如回车,制表符,空格之类的;
reverse操作∶进行字符串的首尾颠倒反转;
upper操作∶将字符串中的英文全变成大写字母;
lower操作∶将字符串中的英文全变成小写字母;
right操作:直接返回字符串中结尾的指定字符;
span_including操作:返回包含指定字符串中任意一个字符的子串
span_excluding操作:返回不包含指定字符串中任意一个字符的子串
format:格式化字符串
replace :替换字符串中的指定字符
stricmp:不区分大小写进行字符串比较
针对当前编码,决定当前内部的指针是char*还是wchar_t*,实际上CString 本身是个模板类,实际上有三种:
CStringA内部使用的是char*,CStringW内部使用的是wchar_t* , CString内部使用的是TCHAR*,所以CString本身会根据当前工程的编码决定使用char*还是wchar_t*,这一点也比较方便.
我们可以先简单使用下 CString,之后改变下工程的编码,看看编译结果就知道了.
先来说说优点:
使用方便,包含了很多实现好的操作,包括 :trim、reverse、format、replace等等;、
无缝兼容MFC;
自适应当前工程编码,智能匹配宽窄字节;
重点,`能实现从窄字节到宽字节的自动转换工作`,即 当前工程编码是宽字节Unicode的前提下,CString支持从char*类型的窄字节字符串来构造和赋值,所以是可以方便的从窄字节转换到宽字节。但是反之则没有办法实现.
|
上一篇: 遍历目录下不同属性类型的文件下一篇: CFile文件的基本操作
|