VC驿站

 找回密码
 加入驿站

QQ登录

只需一步,快速开始

搜索
查看: 2780|回复: 3

[原创] 复杂的宽窄字节数据类型

[复制链接]
83_avatar_middle
最佳答案
0 
在线会员 发表于 2023-9-10 12:44:42 | 显示全部楼层 |阅读模式
# 复杂的宽窄字节数据类型

刚开始学编程的时候我们就接触了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文件的基本操作
29_avatar_middle
最佳答案
0 
在线会员 发表于 2023-9-12 15:15:11 | 显示全部楼层
我靠牛逼,向大佬学习!!!!!
83_avatar_middle
最佳答案
0 
ico_lz  楼主| 发表于 2023-9-19 22:01:31 | 显示全部楼层
哈哈哈,别别
82_avatar_middle
最佳答案
0 
在线会员 发表于 2023-10-4 17:00:36 | 显示全部楼层
本帖最后由 vigiles 于 2023-10-4 17:05 编辑

楼主再细讲讲 std::string复杂的宽窄字节数据类型
您需要登录后才可以回帖 登录 | 加入驿站 qq_login

本版积分规则

×【发帖 友情提示】
1、请回复有意义的内容,请勿恶意灌水;
2、纯数字、字母、表情等无意义的内容系统将自动删除;
3、若正常回复后帖子被自动删除,为系统误删的情况,请重新回复其他正常内容或等待管理员审核通过后会自动发布;
4、感谢您对VC驿站一如既往的支持,谢谢合作!

关闭

站长提醒上一条 /2 下一条

QQ|小黑屋|手机版|VC驿站 ( 辽ICP备09019393号-4 )|网站地图wx_jqr

GMT+8, 2024-2-22 13:15

Powered by CcTry.CoM

© 2009-2021 cctry.com

快速回复 返回顶部 返回列表