【问题标题】:wchar_t to unsigned char conversionwchar_t 到无符号字符的转换
【发布时间】:2018-08-12 14:49:53
【问题描述】:

我有一个实现以下内容的代码:

unsigned char charStr; //this var can only take a value either 0, 1, or 2
WCHAR wcharStr;
...
charStr = wcharStr - '0';
...

我知道在从 Unicode(wchar_t 数据类型)转换为 ANSI(无符号字符)时,您可能会丢失一些数据(从 16 位到 8 位)。但是,有人可以解释为什么减去“0”会使这种转换正确吗?

【问题讨论】:

  • 它没有做你认为它做的事情。
  • 这取决于上下文。通常当 c 是一个数字时你会做c-'0' 并且你想得到这个数字的表示。
  • 这些都不是字符串,为什么要这样命名?
  • 第 1 步请不要再将wchar_t 视为“Unicode”,或将char 视为“ANSI”。
  • @ekremer 当我谈到一个数字的表示时,我的意思是:1 是一个数字,它的表示是'1',它是一个值为 49 的数字常量(该值由ASCII 表)

标签: c++ c unicode ansi


【解决方案1】:

C 和 C++ 语言标准要求从 09 的数字的编码是连续的。因此,例如,减去'4' - '0' 将得到4

这实际上对于wchar_t 不是必需的,但在现实世界中,您的编译器会将其映射到 Unicode,在 Windows 上为 UTF-16 或在其他地方为 UCS-4。 Unicode 的前 128 个代码点与 ASCII 相同。您没有在使用非 ASCII 字符集(IBM 的 Z 系列大型机,默认为代码页 1047 以实现向后兼容性)的现代现实世界编译器上编译此代码,因此您的编译器将您的 wchar_tchar 到某个整数类型,可能是 32 位宽,减去,并得到一个数字值。然后将其存储在unsigned char 类型的变量中,这是一个错误,因为它实际上是不可打印控制字符的 ASCII 值。

此代码不正确。如果您想从wchar_t 转换为char,您应该使用来自STL 的codecvt 或来自C 标准库的wcrtomb()。还有一个wctob() 当且仅当可能时转换为单个字节。在使用它们之前设置您的语言环境。

如果您确定您的 wchar_t 包含 Unicode,您的 unsigned char 包含 Latin-1,并且您的值在范围内,但是,您可以简单地将 wchar_t 值转换为 (unsigned char)。如果您知道自己有数字,另一种方法是写(charStr - L'0') + '0'

【讨论】:

  • 有趣的是,我的wctob 手册页说:永远不要使用这个功能。它不能帮助你编写国际化程序。
  • @Pablo 在 Linux 上这样做的理由是,“国际化程序绝不能区分单字节和多字节字符。”所以,无论如何,这段代码已经违反了这个建议。但转换为多字节字符串以获得更好的可移植性。
  • 为了让生活更加有趣,IBM 的 Z 系列大型机也使用 2 字节的 wchar_t。
猜你喜欢
  • 2013-01-25
  • 2015-02-15
  • 2012-08-10
  • 1970-01-01
  • 2011-11-04
  • 1970-01-01
  • 2014-04-27
  • 2011-10-25
  • 2012-06-03
相关资源
最近更新 更多