C++/Qt中文显示乱码与string/wstring/wchar_t转换

        程序显示汉字乱码,这是因为汉字需要用2个字节来进行编码,英文用一个字节编码。所以得使用占2个字节的变量类型来存放汉字。

(1)char类型,占一个字节,char ch = ‘s’;

      wchar_t类型宽字符,一个whcart_t占2个字节,wchar_t var1 = L'你';wchar_t var2[3] = L"你好";

(2)string是以char作为模板参数的模板类实例,所以汉字对于char和string都是不能正常显示。

    wstring是以wchar_t作为模板参数的模板类实例,所以wstring和wchar_t可以用来存储汉字并正常显示。

string与wstring在windows平台的转换方法如下:


#include <Windows.h>
wstring stringTowstring(string str)  
{  
    wstring result;  
    //获取缓冲区大小,并申请空间,缓冲区大小按字符计算  
    int len = MultiByteToWideChar(CP_ACP, 0, str.c_str(), str.size(), NULL, 0);  
    TCHAR* buffer = new TCHAR[len + 1];  
    //多字节编码转换成宽字节编码  
    MultiByteToWideChar(CP_ACP, 0, str.c_str(), str.size(), buffer, len);  
    buffer[len] = '\0';             //添加字符串结尾  
    //删除缓冲区并返回值  
    result.append(buffer);  
    delete[] buffer;  
    buffer = NULL;
    return result;  
}  
//将wstring转换成string  
string wstring2string(wstring wstr)  
{  
    string result;  
    //获取缓冲区大小,并申请空间,缓冲区大小事按字节计算的  
    int len = WideCharToMultiByte(CP_ACP, 0, wstr.c_str(), wstr.size(), NULL, 0, NULL, NULL);  
    char* buffer = new char[len + 1];  
    //宽字节编码转换成多字节编码  
    WideCharToMultiByte(CP_ACP, 0, wstr.c_str(), wstr.size(), buffer, len, NULL, NULL);  
    buffer[len] = '\0';  
    //删除缓冲区并返回值  
    result.append(buffer);  
    delete[] buffer;  
    return result;  
} 

wstring 与wchar转换: 

    std::wstring strWs = L"CUST";
    wchar_t str[20] = {0};
    swprintf_s(str,19,L"%s",strWs.c_str());

跨平台的转化方法如下:


#include <cstdlib>
#include <string.h>
#include <string>
 
// wstring => string
std::string WString2String(const std::wstring& ws)
{
    std::string strLocale = setlocale(LC_ALL, "");
    const wchar_t* wchSrc = ws.c_str();
    size_t nDestSize = wcstombs(NULL, wchSrc, 0) + 1;
    char *chDest = new char[nDestSize];
    memset(chDest,0,nDestSize);
    wcstombs(chDest,wchSrc,nDestSize);
    std::string strResult = chDest;
    delete []chDest;
    setlocale(LC_ALL, strLocale.c_str());
    return strResult;
}
 
// string => wstring
std::wstring String2WString(const std::string& s)
{
    std::string strLocale = setlocale(LC_ALL, ""); 
    const char* chSrc = s.c_str();
    size_t nDestSize = mbstowcs(NULL, chSrc, 0) + 1;
    wchar_t* wchDest = new wchar_t[nDestSize];
    wmemset(wchDest, 0, nDestSize);
    mbstowcs(wchDest,chSrc,nDestSize);
    std::wstring wstrResult = wchDest;
    delete []wchDest;
    setlocale(LC_ALL, strLocale.c_str());
    return wstrResult;
}

文章中有些内容参考与:

string和wstring的互转_老王的专栏-CSDN博客_string转wstring

C++进阶—>带你理解多字节编码与Unicode码_小伟锅的博客-CSDN博客

注:

1、字符串前面加L表示该字符串是Unicode字符串,每个字符占用两个字节。  
  eg: 
  strlen("asd") = 3;   
  strlen(L"asd") = 6;  
  2、 _T宏可以把一个引号引起来的字符串,根据你的环境设置,使得编译器会根据编译目标环境选择合适的(Unicode还是ANSI)字符处理方式  。TEXT,_TEXT 和_T 一样的  

  如果你定义了UNICODE,那么_T宏会把字符串前面加一个L。这时 _T("ABCD") 相当于 L"ABCD" ,这是宽字符串。 
  如果没有定义,那么_T宏不会在字符串前面加那个L,_T("ABCD") 就等价于 "ABCD"  。

“L”与_T的介绍参考与C++中L的意思_GPNU-IOT的博客-CSDN博客_c++ l

  • 0
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值