ANSI(字符集) and Unicode(字符集) and UTF-8(编码Unicode字符集)

26 篇文章 1 订阅
为什么要Unicode?

ANSI一个字节(8位) 表示一个字符
但是很多世界上其他的语言无法表示,但是又想每个字符都平等对待,所以需要更长的位
Unicode两个字节(16位)来 表示一个国际字符,这样世界上任何国家的任何字符都可以用两个字节统一表示

对C++而言如何表示Unicode?
char正好是 8位,可以用来表示一个ANSI字符
wchar_t正好是 16位,可以表示一个Unicode字符

Unicode统一码?
Unicode: 统一码,包含世界上各个国家的全部语言文字,字符。1994年出第一版。 标准内容是每一个字符的序号ID。
范围: 目前的Unicode字符分为17组编排,0x0000 至 0x10FFFF,每组称为平面(Plane),而每平面拥有65536个码位,共1,114,112个

从Unicode ID到内存表示?
Unicode仅仅规定了一个Unicode字符的序号,并没有规定在内存中用几个字节是否固定字节还是变长字节所以,Unicode在内存中的实现有常见的两种方式,变长编码,定长编码
定长与变长UTF-8?
(1)变长编码:多个字节表示一个字符,UTF-8:char:string:,适合网络传输(压缩原理:经常使用的字符用较少字节,不经常使用的字符用较多字节表示)
(2)定长编码:两个字节表示一个字符,UTF-16:wchar_t :wstring:
CString同时支持两种不同的Unicode内存表示
CString使用TCHAR中间类型,由编译选项来决定是char 还是wchar_t
_T("中间类型的字符串");最终生成代码是wchar_t还是char取决于编译选项是Unicode还是多字节,所以代码中都应该使用中间类型字符串_T("")
宽字符初始化L"",L是用来初始化一个wchar_t字符串常量的。char 字符串常量的初始化只需要""双引号即可。
typedef ATL::CStringT< TCHAR, StrTraitMFC_DLL< TCHAR > > CString;
(1) 编译选项如果设置为Unicode:CString<- TCHAR<- WCHAR<- wchar_t<-wstring.c_str()
(2) 编译选项如果设置为多字节:CString<- TCHAR<- char<-string.c_str()

UTF-8编码在两种编译选项下CString与string之间的转换
(1)Unicode:此时CString使用wchar_t表示q
           string转CString
            CString().Format("%s",string.c_str());//wchar_t只存储一个char的内容,此时多字节的UTF-8中的每一个字节(而不是每一个字符)就会被CString当做是一个UTF-16字符,从而产生乱码
              正确的做法是 使用MultiByteToWideChar系统函数进行转换:将多字节的每一个字符(多字节的字符)转换为一个固定长(wchar_t保存)的字符(UTF-16)
            CString转string
            同样的需要转码:WideCharToMultiByte
(2)多字节:此时CString使用char表示,所以本质上(编码与存储方式)是相同的
             CString cs(L"中国");
            std::cout<<cs.GetBuffer()<<std::endl;//中国
            std::string s(cs.GetBuffer());
            std::cout<<s.c_str()<<std::endl;//中国
            CString cs_from_str(s.c_str());
            std::cout<<cs_from_str.GetBuffer()<<std::endl;
上面的代码在Unicode下面 不能通过编译:wchar_t不能和char不能进行隐式类型转换

Windows转码函数:

CString与string之间的转换
//std::string UnicodeToANSI( const std::wstring& str )
//{
//
//    char*     pElementText;
//    int    iTextLen;
//    // wide char to multi char
//    iTextLen = WideCharToMultiByte( CP_ACP,
//        0,
//        str.c_str(),
//        -1,
//        NULL,
//        0,
//        NULL,
//        NULL );
//    pElementText = new char[iTextLen + 1];
//    memset( ( void* )pElementText, 0, sizeof( char ) * ( iTextLen + 1 ) );
//    ::WideCharToMultiByte( CP_ACP,
//        0,
//        str.c_str(),
//        -1,
//        pElementText,
//        iTextLen,
//        NULL,
//        NULL );
//    std::string strText(pElementText);
//    delete[] pElementText;
//    return strText;
//}

//std::wstring ANSIToUnicode( const std::string& str )
//{
//    int  len = 0;
//    len = str.length();
//    int  unicodeLen = ::MultiByteToWideChar( CP_ACP,
//        0,
//        str.c_str(),
//        -1,
//        NULL,
//        0 ); 
//    wchar_t *  pUnicode; 
//    pUnicode = new  wchar_t[unicodeLen+1]; 
//    memset(pUnicode,0,(unicodeLen+1)*sizeof(wchar_t)); 
//    ::MultiByteToWideChar( CP_ACP,
//        0,
//        str.c_str(),
//        -1,
//        (LPWSTR)pUnicode,
//        unicodeLen ); 
//    std::wstring  rt(( wchar_t* )pUnicode); 
//    delete  pUnicode;
//
//    return  rt;  
//}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

C++程序员Carea

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值