为什么这个角色转换不起作用?

时间:2012-01-17 19:10:21

标签: c++ visual-studio character-encoding

Visual Studio 2008

项目编译为多字节字符集

LPWSTR lpName[1] = {(WCHAR*)_T("Setup")};

转换后,lpName[0]包含垃圾(至少在VS中预览时)

LPWSTR的typedef如下:
typedef __nullterminated WCHAR *NWPSTR, *LPWSTR, *PWSTR;

2 个答案:

答案 0 :(得分:1)

这是我上面评论的扩展版本。

显示的代码将类型A的指针强制转换为类型B的指针。这是一种低级别的,与机器相关的操作。它几乎从不作为A类对象到B类对象的转换,特别是,如果一种类型是常规字符类型而另一种是宽字符。

想象一下,你拿一本法语书,并大声朗读,好像它是用英文写的。

FRENCH* book;
readaloud ((ENGLISH*) book);

你几乎会听到胡言乱语。两种语言中使用的字母是相同的(或者类似的,无论如何),但两种语言的规则完全不同。两种语言的表示相同,但​​意思不是。

这与我们在这里非常相似。无论你有什么类型,比特和字节是相同的,但规则是完全不同的。您根据常规字符规则获取布局,并尝试根据宽字符规则对其进行解释。它不起作用。两种情况下的表示都是相同的,但意思不是。

要将一个字符的味道转换为另一个,你通常需要一个查找表或一些其他方法将每个字符从一种类型转换为另一种 - 更改表示,但保留含义。同样,要将法语书籍转换成英语书籍,你需要使用一个大的查找表a.k.a.字典......好吧,这里的比喻打破了,因为没有正式的转换规则集,你需要有创意!但是你明白了。

C ++的规则实际上禁止这样的演员表。您只能将对象类型poiner转换为void*,并仅使用结果将其强制转换回原始对象类型。其他一切都是禁忌(除非你愿意冒险进行未定义的行为)。

那你该怎么办?

  1. 选择一个字符变体并坚持下去。
  2. 如果必须在各种口味之间进行转换,请使用库函数进行转换。
  3. 尽量避免使用指针转换,它们几乎总是发出麻烦。

答案 1 :(得分:0)

我认为您正在寻找的是

LPTSTR lpName[1] = {_T("Setup")};

其中包含T的各种typedef(例如TSTRLPTSTR)取决于您是使用unicode还是多字节或其他任何内容。通过使用它们,您应该能够编写以您正在使用的任何编码工作的代码(即,明天您可以切换到ascii,并且您的代码的大部分仍然可以工作)。

修改

如果您确实需要在编码之间进行转换,则可以使用各种转换功能,例如wcstombs(或microsoft's documentation)和mbstowcs。这些在<cstdlib>

中定义