【问题标题】:Why doesn't this character conversion work?为什么这个字符转换不起作用?
【发布时间】:2012-01-18 04:19:45
【问题描述】:

Visual Studio 2008

项目编译为多字节字符集

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

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

LPWSTR 的类型定义如下:
typedef __nullterminated WCHAR *NWPSTR, *LPWSTR, *PWSTR;

【问题讨论】:

  • 如果你正在为_MBCS 编译,那么_T 不宽。您可能需要L"string goes here",然后就不需要(WCHAR*) 演员表。
  • 哦,我明白了这个问题。它不起作用,因为它不是一个 crracter 转换。这是一个指针转换。字符转换是通过字符转换函数完成的。

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


【解决方案1】:

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

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

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

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

您通常会听到胡言乱语。两种语言中使用的字母相同(或至少相似),但两种语言的规则完全不同。两种语言的表示相同,但​​含义不同。

这与我们这里的非常相似。无论你有什么类型,位和字节都是一样的,但规则完全不同。您根据常规字符规则排列位,并尝试根据宽字符规则来解释它们。它不起作用。两种情况下的表示相同,但​​含义不同。

要将一种字符风格转换为另一种风格,您通常需要一个查找表或其他方法来将每个字符从一种类型转换为另一种类型 - 更改表示,但保留含义。同样,要将法语书籍转换为英语书籍,您需要使用一个大查找表(也称为字典)......好吧,这个类比在这里中断,因为没有正式的转换规则集,您需要有创意!但你明白了。

C++ 的规则实际上禁止这种类型转换。您只能将对象类型指针转换为void*,并且只能使用结果将其转换回原始对象类型。其他一切都是禁忌(除非您愿意冒险进入未定义行为的领域)。

那你该怎么办?

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

【讨论】:

  • 感谢您最有说服力的解释 - Andrew S.
【解决方案2】:

我认为你正在寻找的是

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

带有T 的各种类型定义(例如TSTRLPTSTR)取决于您使用的是unicode 还是多字节或其他。通过使用这些,您应该能够编写以您正在使用的任何编码工作的代码(即,明天您可以切换到 ascii,并且您的大部分代码应该仍然可以工作)。

编辑

如果您确实必须在编码之间进行转换,那么可以使用各种转换函数,例如wcstombs(或microsoft's documentation)和mbstowcs。这些定义在<cstdlib>

【讨论】:

猜你喜欢
  • 2021-12-20
  • 2022-01-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-04
  • 2012-11-30
  • 2011-11-02
相关资源
最近更新 更多