ANSI字符串转换为UNICODE字符串

GARY 2010-12-29 03:01:00
我的测试代码如下:
————————————————————————————————
char *pszText = "ANSI字符串转换为UNICODE字符串!";
int cchWideChar = MultiByteToWideChar(CP_ACP, 0, pszText, -1, NULL, 0);
PTCHAR ptszText = NULL;
ptszText = new TCHAR[cchWideChar];
if(!ptszText){
delete [] ptszText;
}
MultiByteToWideChar(CP_ACP, 0, pszText, -1, ptszText, cchWideChar);
MessageBox(ptszText);
delete [] ptszText;
————————————————————————————————
使用起来,也没发现问题,转换也成功了。
我在读《Windows核心编程》的时候,读到相关的章节时,写到以下内容:

我的疑问是:
核心编程的这段话中的第3条,“再次调用MultiByteToWideChar,将第一次MultiByteToWideChar
调用的返回值乘以sizeof(wchar_t)后得到的大小做为cchWideChar参数的值传入”
而我的代码中实际上传入的只是MultiByteToWideChar第一次调用时的返回值,并没有乘以
sizeof(wchar_t),程序仍然运行的好好的。因为我在读MSDN的时候,有关cchWideChar这个参数的介绍,
“The size, in wide characters, of the buffer pointed to by the lpWideCharStr parameter. ”
也就是cchWideChar应该是wide characters字符数而不是字节数,所以我认为不必要去乘以sizeof(wchar_t)。
而且现在我的代码也没发现什么问题。
我想让大家指点我一下,我的代码到底对不对,到底应不应该乘以sizeof(wchar_t)。谢谢。
...全文
544 22 打赏 收藏 转发到动态 举报
写回复
用AI写文章
22 条回复
切换为时间正序
请发表友善的回复…
发表回复
GARY 2010-12-30
  • 打赏
  • 举报
回复
int cchWideChar = MultiByteToWideChar(CP_ACP, 0, pszText, -1, NULL, 0);
MultiByteToWideChar(CP_ACP, 0, pszText, -1, ptszText, cchWideChar);
帖子结了,但是继续看《Windows核心编程》的时候,发现最后一个参数并不用
cchWideChar*sizeof(wchar_t)
也就是并不用乘以sizeof(wchar_t)
Eleven 2010-12-29
  • 打赏
  • 举报
回复
[Quote=引用 20 楼 joyzml 的回复:]
引用 18 楼 visualeleven 的回复:
C/C++ code
char *pszText = "ANSI字符串转换为UNICODE字符串!";
int cchWideChar = MultiByteToWideChar(CP_ACP, 0, pszText, -1, NULL, 0);
PTCHAR ptszText = NULL; // 这里你应该写PWCHAR,或者wcha……
[/Quote]
delete空指针是安全的,不会出错
operator delete
The complement to the new-expression is the delete-expression, which first calls the destructor and then releases the memory (often with a call to free( )). Just as a new-expression returns a pointer to the object, a delete-expression requires the address of an object.
delete fp;
This destructs and then releases the storage for the dynamically allocated MyType object created earlier.
delete can be called only for an object created by new. If you malloc( ) (or calloc( ) or realloc( )) an object and then delete it, the behavior is undefined. Because most default implementations of new and delete use malloc( ) and free( ), you’d probably end up releasing the memory without calling the destructor.
If the pointer you’re deleting is zero, nothing will happen. For this reason, people often recommend setting a pointer to zero immediately after you delete it, to prevent deleting it twice. Deleting an object more than once is definitely a bad thing to do, and will cause problems.
GARY 2010-12-29
  • 打赏
  • 举报
回复
[Quote=引用 18 楼 visualeleven 的回复:]
C/C++ code
char *pszText = "ANSI字符串转换为UNICODE字符串!";
int cchWideChar = MultiByteToWideChar(CP_ACP, 0, pszText, -1, NULL, 0);
PTCHAR ptszText = NULL; // 这里你应该写PWCHAR,或者wchar_t* ptszText = NULL;
ptsz……
[/Quote]
谢谢部长,这个我好像看别的帖子也看到过,确实是。
“// 这里下面没必要,如果ptszText为NULL,下面的delete完全没有必要,delete空指针不会出错”
您是不是说,delete空指针会出错吧。
Sou2012 2010-12-29
  • 打赏
  • 举报
回复
wstring ansi_2_unicode(const char *p_in)
{
int nLen = MultiByteToWideChar(CP_ACP, 0, p_in, -1, NULL, 0);
wchar_t *p_out = new wchar_t[nLen];
memset(p_out, 0, nLen);
MultiByteToWideChar(CP_ACP, 0, p_in, -1, p_out, nLen);
wstring s_out(p_out);
SAFE_DELETE_ARRAY(p_out);
return s_out;
}
Eleven 2010-12-29
  • 打赏
  • 举报
回复
char *pszText = "ANSI字符串转换为UNICODE字符串!";
int cchWideChar = MultiByteToWideChar(CP_ACP, 0, pszText, -1, NULL, 0);
PTCHAR ptszText = NULL; // 这里你应该写PWCHAR,或者wchar_t* ptszText = NULL;
ptszText = new TCHAR[cchWideChar];
// 这里下面没必要,如果ptszText为NULL,下面的delete完全没有必要,delete空指针不会出错
if(!ptszText){
delete [] ptszText;
}
MultiByteToWideChar(CP_ACP, 0, pszText, -1, ptszText, cchWideChar);
MessageBox(ptszText);
delete [] ptszText;

指出一下你上面的错误
GARY 2010-12-29
  • 打赏
  • 举报
回复
好吧。多谢所有回帖的朋友,一会回来结贴给分。
GARY 2010-12-29
  • 打赏
  • 举报
回复
14楼,嗯。我就是怕以后出问题,所以才来问清楚。
好吧,我就cchWideChar*sizeof(wchar_t)吧。
可能是《Windows核心编程》上面还有一段内容让我理解不清了。

因为它这里,强调的是字符数。
GARY 2010-12-29
  • 打赏
  • 举报
回复
我的代码是Unicode的工程
因为我的程序都是写在windows ce下的。
Jimmy_Xia 2010-12-29
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 joyzml 的回复:]

11楼的哥哥,也就是第二次调用MultiByteToWideChar时是:
MultiByteToWideChar(CP_ACP, 0, pszText, -1, ptszText, cchWideChar*sizeof(wchar_t));
必须要乘以sizeof(wchar_t)?
[/Quote]
为了你程序的健壮性,虽然目前你的程序没有表现出问题。不过一旦出问题,你都不知道哪里的问题。
GARY 2010-12-29
  • 打赏
  • 举报
回复
11楼的哥哥,也就是第二次调用MultiByteToWideChar时是:
MultiByteToWideChar(CP_ACP, 0, pszText, -1, ptszText, cchWideChar*sizeof(wchar_t));
必须要乘以sizeof(wchar_t)?
GARY 2010-12-29
  • 打赏
  • 举报
回复
谢谢楼上几位哥哥。可是能不能正面回答一下我的问题。
我的问题在6楼已经描述了,就是第二次调用MultiByteToWideChar时是:
MultiByteToWideChar(CP_ACP, 0, pszText, -1, ptszText, cchWideChar*sizeof(wchar_t));
还是
MultiByteToWideChar(CP_ACP, 0, pszText, -1, ptszText, cchWideChar);

我的问题不是new,不是怎么来转换,不是用哪些宏方便,也不是用ATL好不好。

谢谢7楼大侠,就是说第二次调用MultiByteToWideChar,最后一个参数只是第一次调用
MultiByteToWideChar的返回值就行了,不必*sizeof(wchar_t)吧?
Jimmy_Xia 2010-12-29
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 joyzml 的回复:]

也就是说按核心编程的意思,第二次调用MultiByteToWideChar时,应该是:
MultiByteToWideChar(CP_ACP, 0, pszText, -1, ptszText, cchWideChar*sizeof(wchar_t));
而我的是:
MultiByteToWideChar(CP_ACP, 0, pszText, -1, ptszText, cchWideChar);

不知道这次我说明白问题没有。多谢大家。
[/Quote]
特地试了试,你的这种方式编译的如果是ANSI的,程序是有错误的,转换出来的字符占用的内存空间越界了。
所以,你还是需要按照书上说明的去做比较好。
muzizongheng 2010-12-29
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 joyzml 的回复:]
谢谢楼上几位大神:
不过我的疑问不是new这里对不对
ptszText = new TCHAR[cchWideChar];

而是:
我的代码中第二次调用MultiByteToWideChar时
MultiByteToWideChar(CP_ACP, 0, pszText, -1, ptszText, cchWideChar);
最后一个参数传入的是cchWideChar,也就是第一……
[/Quote]

就是说调用2次multibytetowidechar, 第一次是为了确认转换后需要的buffer大小, 因为buffer不够转换会失败, 函数返回值就是需要的长度。 然后第二次调用就能正确成功。
bai_shou 2010-12-29
  • 打赏
  • 举报
回复
ATL 的函数可以很容易转。


#include <atlbase.h>

//使用ATL的W2A和A2W宏必须使用USES_CONVERSION
USES_CONVERSION;

//Unicode字符串
wchar_t* wszText=L"1.Unicode字符转换为ANSI;";
printf("%s\n",W2A(wszText));

//用wprintf输出非英文字符,需要设置当前的地域信息
setlocale(LC_ALL,"chs");

//ANSI字符串(ANSI:American National Standards Institute)
//中文内码MBCS:Multi-Byte character sets,英文内码SBCS:Single-Byte character sets)
char* szText="2.ANSI字符转换成Unicode.";
wprintf(L"%s\n",A2W(szText));
lizhigang34 2010-12-29
  • 打赏
  • 举报
回复
因为这个比较常用,所以,我将字符转换定义了几个宏


//将ANSI字符串,转成UNICODE
#define AnsiStr2UnicodeStr(szA, szW) { int nLenOfWideCharStr; nLenOfWideCharStr = MultiByteToWideChar(CP_ACP, 0, szA, -1, NULL, 0); MultiByteToWideChar(CP_ACP, 0, szA, -1, szW, nLenOfWideCharStr);}

//将UNICODE字符串,转成ANSI
#define UnicodeStr2AnsiStr(pA, pW, pAStrLen){ int ret = WideCharToMultiByte(CP_ACP, 0, pW, -1, pA, 1024, NULL, NULL); *pAStrLen = ret-1; }

//将CString转换成char*
#define CStr2AnsiStr(cstr, pszA, pAStrLen){ LPCWSTR lpwName = cstr.GetBuffer(); UnicodeStr2AnsiStr(pszA, lpwName, &pAStrLen);}

//将char*转换成CString
#define AnsiStr2CStr(cstr, pszA){ WCHAR wstrName[1024] = {0};AnsiStr2UnicodeStr(pszA, wstrName);cstr.Format(L"%s", wstrName);}


Eleven 2010-12-29
  • 打赏
  • 举报
回复
char *pszText = "ANSI×Ö·û´®×ª»»ÎªUNICODE×Ö·û´®£¡";
int cchWideChar = MultiByteToWideChar(CP_ACP, 0, pszText, -1, NULL, 0);
wchar_t* ptszText = NULL;
ptszText = new wchar_t[cchWideChar];
// 或者 ptszText = (wchar_t*)malloc(cchWideChar * sizeof(wchar_t));

MultiByteToWideChar(CP_ACP, 0, pszText, -1, ptszText, cchWideChar);
AfxMessageBox(CString(ptszText));
delete [] ptszText;
ptszText = NULL;
GARY 2010-12-29
  • 打赏
  • 举报
回复
谢谢楼上几位大神:
不过我的疑问不是new这里对不对
ptszText = new TCHAR[cchWideChar];

而是:
我的代码中第二次调用MultiByteToWideChar时
MultiByteToWideChar(CP_ACP, 0, pszText, -1, ptszText, cchWideChar);
最后一个参数传入的是cchWideChar,也就是第一次调用
MultiByteToWideChar的返回值。
而核心编程的第三条中说道:
“再次调用MultiByteToWideChar,将第一次MultiByteToWideChar
调用的返回值乘以sizeof(wchar_t)后得到的大小做为cchWideChar参数的值传入”

也就是说按核心编程的意思,第二次调用MultiByteToWideChar时,应该是:
MultiByteToWideChar(CP_ACP, 0, pszText, -1, ptszText, cchWideChar*sizeof(wchar_t));
而我的是:
MultiByteToWideChar(CP_ACP, 0, pszText, -1, ptszText, cchWideChar);

不知道这次我说明白问题没有。多谢大家。


oyljerry 2010-12-29
  • 打赏
  • 举报
回复
TCHAR 宏区分出Unicode,ANSI了,所以分配的时候刚好,但是比较好的方式是调用两次,第一次获得大小,第二次再转换
Eleven 2010-12-29
  • 打赏
  • 举报
回复
Sorry;

ptszText = (wchar_t*)new[cchWideChar];
-->
ptszText = new[cchWideChar];
Eleven 2010-12-29
  • 打赏
  • 举报
回复
如果你使用new来分配,则不用加; 如果使用malloc来分配,则需要
wchar* ptszText = NULL;
....

ptszText = (wchar_t*)new[cchWideChar];
ptszText = (wchar_t*)malloc(cchWideChar*sizeof(wchar_t));
加载更多回复(2)

16,473

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧