`
aigo
  • 浏览: 2648851 次
  • 性别: Icon_minigender_1
  • 来自: 宜昌
社区版块
存档分类
最新评论

Unicode下CString(wchar_t)转换为 char* (转)

 
阅读更多

原文具体的地址不清楚,网上转载的太多了

 

平台VC2005,使用Unicode字符集。因为以前一直是用多字节字符集的,使用的str开头的函数都要转换成_wcs,烦,最后,被CString类型无法转换为char*或char[]的错误搞得是火大了。

 

使用以前转换CString的方法或者网上别人的指导用法,都失效了

1. strcpy_s( pchar, sizeof(pchar), mCString.GetBuffer(mCString.GetLength()) );不行,mCString.GetBuffer()返回的是wchar_t数组,使用Unicode字符集时,wchar_t无法自动转换为char*.

 

2. strcpy_s(pchar, sizeof(pchar), (LPCSTR)_bstr_t(mCString));不行,"_bstr_t找不到识别符"

 

3. char *pch = (T2A)(LPSTR)(LPCTSTR)mCString; 也不行,"T2A是没声明的标识符",我补加上相应头文件AtlConv.h或AtlBase.h等的,也还是报错不改。

 

4. char *pch = (LPSTR)(LPCTSTR)mCString; 这样没有报错,但pch只能获得CString的第一个字符而已,第一个换成(char*),也只能获取第一个字符。郁闷。

 

5. CString.GetBuffer(CString.GetLength())不行。w_char*不能转为_char*。

 

正确方法:

wstring MultCHarToWideChar(string str)
{
    //获取缓冲区的大小,并申请空间,缓冲区大小是按字符计算的
    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';//添加字符串结尾
    //删除缓冲区并返回值
    wstring return_value;
    return_value.append(buffer);
    delete []buffer;
    return return_value;
}
string WideCharToMultiChar(wstring str)
{
    string return_value;
    //获取缓冲区的大小,并申请空间,缓冲区大小是按字节计算的
    int len=WideCharToMultiByte(CP_ACP,0,str.c_str(),str.size(),NULL,0,NULL,NULL);
    char *buffer=new char[len+1];
    WideCharToMultiByte(CP_ACP,0,str.c_str(),str.size(),buffer,len,NULL,NULL);
    buffer[len]='\0';
    //删除缓冲区并返回值
    return_value.append(buffer);
    delete []buffer;
    return return_value;
}

 

 

于是使用

string mstring = WideCharToMultiChar( (LPCTSTR)mCString );

strcpy_s( pach, sizeof(pach), mstring.c_str() );

转换成功

MultiByteToWideChar的与WideCharToMultiByte的参数详解

 

第一个就是宽字符到多字节字符转换函数,函数原型如下:

 

int WideCharToMultiByte(
UINT CodePage,
DWORD dwFlags,
LPCWSTR lpWideCharStr,
int cchWideChar,
LPSTR lpMultiByteStr,
int cbMultiByte,
LPCSTR lpDefaultChar,
LPBOOL lpUsedDefaultChar
);

 

 

此函数把宽字符串转换成指定的新的字符串,如ANSI,UTF8等,新字符串不必是多字节字符集。参数:

 

CodePage: 指定要转换成的字符集代码页,它可以是任何已经安装的或系统自带的字符集,你也可以使用如下所示代码页之一。

 

CP_ACP 当前系统ANSI代码页

CP_MACCP 当前系统Macintosh代码页

CP_OEMCP 当前系统OEM代码页,一种原始设备制造商硬件扫描码

CP_SYMBOL Symbol代码页,用于Windows 2000及以后版本,我不明白是什么

CP_THREAD_ACP 当前线程ANSI代码页,用于Windows 2000及以后版本,我不明白是什么

CP_UTF7 UTF-7,设置此值时lpDefaultChar和lpUsedDefaultChar都必须为NULL

CP_UTF8 UTF-8,设置此值时lpDefaultChar和lpUsedDefaultChar都必须为NULL

 

我想最常用的应该是CP_ACP和CP_UTF8了,前者将宽字符转换为ANSI,后者转换为UTF8。

 

dwFlags: 指定如何处理没有转换的字符, 但不设此参数函数会运行的更快一些,我都是把它设为0。 可设的值如下表所示:

WC_NO_BEST_FIT_CHARS 把不能直接转换成相应多字节字符的Unicode字符转换成lpDefaultChar指定的默认字符。也就是说,如果把Unicode转换成多字节字符,然后再转换回来,你并不一定得到相同的Unicode字符,因为这期间可能使用了默认字符。此选项可以单独使用,也可以和其他选项一起使用。

WC_COMPOSITECHECK 把合成字符转换成预制的字符。它可以与后三个选项中的任何一个组合使用,如果没有与他们中的任何一个组合,则与选项WC_SEPCHARS相同。

WC_ERR_INVALID_CHARS 此选项会致使函数遇到无效字符时失败返回,并且GetLastError会返回错误码ERROR_NO_UNICODE_TRANSLATION。否则函数会自动丢弃非法字符。此选项只能用于UTF8。

 

WC_DISCARDNS 转换时丢弃不占空间的字符,与WC_COMPOSITECHECK一起使用

WC_SEPCHARS 转换时产生单独的字符,此是默认转换选项,与WC_COMPOSITECHECK一起使用

WC_DEFAULTCHAR 转换时使用默认字符代替例外的字符,(最常见的如’?’),与WC_COMPOSITECHECK一起使用。

 

当指定WC_COMPOSITECHECK时,函数会将合成字符转换成预制字符。合成字符由一个基字符和一个不占空间的字符(如欧洲国家及汉语拼音的音标)组成,每一个都有不同的字符值。预制字符有一个用于表示基字符和不占空间字符的合成体的单一的字符值。

当指定WC_COMPOSITECHECK选项时,也可以使用上表列出的最后3个选项来定制预制字符的转换规则。这些选项决定了函数在遇到宽字符串的合成字符没有对应的预制字符时的行为,他们与WC_COMPOSITECHECK一起使用,如果都没有指定,函数默认WC_SEPCHARS。

 

对于下列代码页,dwFlags必须为0,否则函数返回错误码ERROR_INVALID_FLAGS。

50220 50221 50222 50225 50227 50229 52936 54936 57002到57011 65000(UTF7) 42(Symbol)

对于UTF8,dwFlags必须为0或WC_ERR_INVALID_CHARS,否则函数都将失败返回并设置错误码ERROR_INVALID_FLAGS,你可以调用GetLastError获得。

 

lpWideCharStr: 待转换的宽字符串。

 

cchWideChar: 待转换宽字符串的长度,-1表示转换到字符串结尾。

 

lpMultiByteStr: 接收转换后输出新串的缓冲区。

 

cbMultiByte: 输出缓冲区大小,如果为0,lpMultiByteStr将被忽略,函数将返回所需缓冲区大小而不使用lpMultiByteStr。

 

lpDefaultChar: 指向字符的指针, 在指定编码里找不到相应字符时使用此字符作为默认字符代替。 如果为NULL则使用系统默认字符。对于要求此参数为NULL的dwFlags而使用此参数,函数将失败返回并设置错误码ERROR_INVALID_PARAMETER。

 

lpUsedDefaultChar:开关变量的指针,用以表明是否使用过默认字符。对于要求此参数为NULL的dwFlags而使用此参数,函数将失败返回并设置错误码ERROR_INVALID_PARAMETER。lpDefaultChar和lpUsedDefaultChar都设为NULL,函数会更快一些。

 

返回值: 如果函数成功,且cbMultiByte非0,返回写入lpMultiByteStr的字节数(包括字符串结尾的null);cbMultiByte为0,则返回转换所需

 

字节数。函数失败,返回0。

注意:函数WideCharToMultiByte使用不当,会给影响程序的安全。调用此函数会很容易导致内存泄漏,因为lpWideCharStr指向的输入缓冲区大小是宽字符数,而lpMultiByteStr指向的输出缓冲区大小是字节数。为了避免内存泄漏,应确保为输出缓冲区指定合适的大小。我的方法是先使cbMultiByte为0调用WideCharToMultiByte一次以获得所需缓冲区大小,为缓冲区分配空间,然后再次调用WideCharToMultiByte填充缓冲区,详见下面的代码。另外,从Unicode UTF16向非Unicode字符集转换可能会导致数据丢失,因为该字符集可能无法找到表示特定Unicode数据的字符。

 

wchar_t* pwszUnicode = "Holle, word! 你好,中国! ";

int iSize;

char* pszMultiByte;

 

iSize = WideCharToMultiByte(CP_ACP, 0, pwszUnicode, -1, NULL, 0, NULL, NULL);

pszMultiByte = (char*)malloc((iSize+1));

WideCharToMultiByte(CP_ACP, 0, pwszUnicode, -1, pszMultiByte, iSize, NULL, NULL);

 

第二个是多字节字符到宽字符转换函数,函数原型如下:

> int MultiByteToWideChar(

UINT CodePage,

DWORD dwFlags,

LPCSTR lpMultiByteStr,

int cbMultiByte,

LPWSTR lpWideCharStr,

int cchWideChar

);

 

此函数把多字节字符串转换成宽字符串(Unicode),待转换的字符串并不一定是多字节的。

 

此函数的参数,返回值及注意事项参见上面函数WideCharToMultiByte的说明,这里只对dwFlags做简单解释。

 

dwFlags: 指定是否转换成预制字符或合成的宽字符,对控制字符是否使用像形文字,以及怎样处理无效字符。

 

MB_PRECOMPOSED 总是使用预制字符,即有单个预制字符时,就不会使用分解的基字符和不占空间字符。此为函数的默认选项,不能和MB_COMPOSITE合用

MB_COMPOSITE 总是使用分解字符,即总是使用基字符+不占空间字符的方式

MB_ERR_INVALID_CHARS 设置此选项,函数遇到非法字符就失败并返回错误码ERROR_NO_UNICODE_TRANSLATION,否则丢弃非法字符

MB_USEGLYPHCHARS 使用像形字符代替控制字符

 

对于下列代码页,dwFlags必须为0,否则函数返回错误码ERROR_INVALID_FLAGS。

50220 50221 50222 50225 50227 50229 52936 54936 57002到57011 65000(UTF7) 42(Symbol)

对于UTF8,dwFlags必须为0或MB_ERR_INVALID_CHARS,否则函数都将失败并返回错误码ERROR_INVALID_FLAGS。

 

以下函数我没用过,只简要说明之。

 

int GetTextCharset( HDC hdc );

 

此函数获取当前选进的设备描述表的字符集,等同于GetTextCharsetInfo(hdc, NULL, 0)。

 

返回值: 成功返回字符集标识,失败返回DEFAULT_CHARSET。

分享到:
评论

相关推荐

    VC之CString,wchar_t,int,string,char*之间的转换

    `CString`、`wchar_t`、`int`、`string`和`char*`都是编程中常用的字符串和数值类型,它们之间互相转换有助于在不同场景下灵活地处理数据。本篇文章将详细介绍这些类型之间的转换方法。 首先,`CString`是Microsoft...

    CString-const-char-char-to-WCHAR.rar_CString To Char_char wchar_

    要将一个包含宽字符的`CString`对象转换为`const char*`,可以使用`CString`的`MultiByteToWideChar`函数。这个函数将UNICODE字符串转换为多字节字符串,通常用于与非UNICODE API交互。在转换前,你需要确定目标...

    Unicode下CString与char*之间的转换(vs2008绝对实用)

    首先,我们来看Unicode下的CString转换为char*的方法: 1. 使用API `WideCharToMultiByte` 进行转换: ```cpp CString str = _T("D://校内项目//QQ.bmp"); int n = str.GetLength(); // n = 14, len = 18 int ...

    关于char,_wchar_t,_TCHAR,__T(),L,宏__T、TEXT,_TEXT、L.

    它可以处理`char*` 和`_wchar_t*` 类型的字符串,进一步增强了对字符编码的适应性。 7. **`wchar_t`, `int`, `string`, `char` 之间的转换**: 在实际编程中,我们经常需要在这几种类型间进行转换。例如,`wcstombs`...

    Char_Cstring_TCHAR.rar_C++ CString CHAR_Char_Cstring_TCHAR_TCHAR

    CHAR* CStringToChar(CString strCString) { int nLen = WideCharToMultiByte(CP_ACP, 0, (LPCWSTR)strCString, -1, NULL, 0, NULL, NULL); CHAR* pszChar = new CHAR[nLen]; WideCharToMultiByte(CP_ACP, 0, ...

    (const) char 转CString 详解(字符串类型转换详解,不断补充)

    `CString`可以接受`const char*`、`wchar_t*`等不同格式的字符串指针作为输入,并能自动进行适当的编码转换。 #### 2. `const char *`与`CString`之间的转换 从`const char *`到`CString`的转换通常较为直接,因为...

    CString、LPCTSTR、LPTSTR、TCHAR、WCHAR、string、wchar_t、char解析

    本文将深入解析几种常见的字符串类型,包括`CString`、`LPCTSTR`、`LPTSTR`、`TCHAR`、`WCHAR`、`string`、`wchar_t`和`char`。 1. `CString`:`CString`是Microsoft MFC(Microsoft Foundation Classes)库中定义...

    C++各种字符串类型之间进行转换

    将`_bstr_t`转换为`char *`需要先将其转换为`wchar_t *`,然后再转为`char *`。 ```cpp _bstr_t bstr(L"你好,世界!"); wchar_t *wstr = bstr; size_t len = wcslen(wstr) + 1; char *cstring = new char[len]; ...

    浅谈c++ 字符类型总结区别wchar_t,char,WCHAR

    1、区别wchar_t,char,WCHAR ANSI:即 char,可用字符串处理函数:strcat( ),strcpy( ), strlen( )等以str打头的函数。 UNICODE:wchar_t是Unicode字符的数据类型,它实际定义在里: typedef unsigned short wchar_t;...

    VisualC++如何:在各种字符串类型之间进行转换[文].pdf

    本文主要探讨了如何在各种C++字符串类型之间进行转换,包括`char *`、`wchar_t*`、`_bstr_t`、`CComBSTR`、`CString`、`std::basic_string`以及.NET框架中的`System.String`。以下是对这些转换的详细说明: 1. **从...

    cstring的相关知识.docx

    #### 九、char*与wchar_t*之间相互转换 - **wcstombs_s**: 从宽字符字符串转换为多字节字符串。 - **mbstowcs_s**: 从多字节字符串转换为宽字符字符串。 #### 十、利用API实现字符编码的转换 - **...

    BSTR、Char和CString类型的转换.txt

    将C风格的char*字符串转换为MFC的CString对象,可以直接赋值或使用`format`成员函数: ```cpp char chArray[] = "This is a test"; CString theString(chArray); theString.format(_T("%s"), chArray); ``` #### ...

    wince开发用转换类

    static void Gb2312ToUnicode(wchar_t* pstrOut, u32 dwOutLen, const char* pstrIn, u32 dwInLen); static CString string_to_cstring(string text); static int string_to_int(string str); static string cstring...

    CString转UTF8,UTF8转CString

    wchar_t *wszUtf8 = new wchar_t[len + 1]; memset(wszUtf8, 0, len * 2 + 2); MultiByteToWideChar(CP_ACP, 0, (LPCTSTR)str_multi, -1, wszUtf8, len); len = WideCharToMultiByte(CP_UTF8, 0, wszUtf8, -1,...

    (UNICODE 与非UNICODE导致的问题)CString,TCHAR和CHAR类型的互转.docx

    正确处理`CString`、`TCHAR`和`CHAR`之间的转换对于确保代码在UNICODE和非UNICODE环境下的兼容性至关重要。不正确的转换可能导致乱码或者程序运行错误。在编写跨平台或需要兼容不同编码的代码时,这些转换函数是必不...

    string、wstring、cstring、 char、 tchar、int、dword转换方法

    首先,通过`_bstr_t`构造函数将`std::string`的`c_str()`转换为BSTR类型,然后将BSTR类型强制转换为宽字符指针`wchar_t*`,最后将这个指针转换为`std::wstring`对象。 #### `wstring`到`string` ```cpp string ws2s...

    C++中char*转换为LPCWSTR的解决方案

    这里,`A2CW`将`char*`转换为`const wchar_t*`,而`W2A`则是用来从`LPCWSTR`转换回`LPCTSTR`的。 请注意,以上所有方法都在Unicode环境中进行了测试,确保了转换的正确性。在实际项目中,选择哪种方法取决于你的...

    VC++类型转换详解

    13. **wchar\_t**: 16位无符号整型,用于表示Unicode字符,支持更多字符集。 **二.常用数据类型转化** 2.1 **数学类型变量与字符串相互转换** - `std::stringstream`可以用来将数值转换为字符串,反之亦然。 - ...

    转 String,CString,TCHAR,char之间区别和联系

    - 定义了`UNICODE`宏时,`TCHAR`等同于`wchar_t`,用于支持Unicode编码。 使用`TCHAR`可以编写兼容MBCS和Unicode的代码,无需根据不同的编码方式重写代码。 #### 3. `CString` `CString`是Visual C++ MFC类库中的...

    解决2010VC的复制 遇到的CSTRING 向CHAR转换的问题

    这个函数是Windows API的一部分,用于将宽字符(wchar_t)转换为多字节字符序列。其语法如下: ```cpp int WidCharToMultiByte( UINT CodePage, // 指定使用的编码页面 DWORD dwFlags, // 转换标志 LPCWSTR ...

Global site tag (gtag.js) - Google Analytics