_T()宏更改UNICODE字符数据

时间:2010-11-09 11:29:16

标签: c++ c string gcc widechar

我有UNICODE应用程序,我们使用_T(x),定义如下。

#if defined(_UNICODE)
#define _T(x) L ##x
#else
#define _T(x) x
#endif

我知道L被定义为wchar_t,在任何平台上都是4个字节。如果我错了,请纠正我。我的要求是我需要L为2个字节。因此编译器hack我开始使用-fshort-wchar gcc标志。但现在我需要将我的应用程序移动到zSeries,我无法在该平台中看到-fshort-wchar标志的效果。

为了让我能够在zSeries上移植我的应用程序,我需要以这样的方式修改_T()宏,即使在使用L ## x并且不使用-fshort-wchar标志之后,我需要得到2字节宽的字符数据。可以告诉我如何更改L的定义,以便我可以在我的应用程序中将L定义为2个字节。

2 个答案:

答案 0 :(得分:5)

你不能 - 没有c ++ 0x支持。 c ++ 0x定义了以下声明字符串文字的方法:

  • “某些实现定义编码中的字符串字符串” - char
  • u8“utf8字符串” - char
  • 你“utf16字符串” - char16_t
  • U“字符串utf32字符” - char32_t
  • L“某些实现定义编码中的wchar_t字符串” - wchar_t

在广泛支持c ++ 0x之前,以跨平台方式编码utf-16字符串的唯一方法是将其分解为位:

// make a char16_t type to stand in until msvc/gcc/etc supports
// c++0x utf string literals
#ifndef CHAR16_T_DEFINED
#define CHAR16_T_DEFINED
typedef unsigned short char16_t;
#endif

const char16_t strABC[] = { 'a', 'b', 'c', '\0' };
// the same declaration would work for a type that changes from 8 to 16 bits:

#ifdef _UNICODE
typedef char16_t TCHAR;
#else
typedef char TCHAR;
#endif
const TCHAR strABC2[] = { 'a', 'b', 'b', '\0' };

_T宏只能在wchar_t为16位宽的平台上交付货物。并且,替代方案仍然不是真正的跨平台:char和wchar_t的编码是实现定义的,因此'a'不一定编码'a'(0x61)的unicode代码点。因此,为了严格准确,这是编写字符串的唯一方法:

const TCHAR strABC[] = { '\x61', '\x62', '\x63', '\0' };

这太可怕了。

答案 1 :(得分:0)

啊!便携性的奇迹: - )

如果您的所有平台都有C99编译器,请使用int_least16_t中的uint_least16_t<stdint.h>,....大多数平台也定义int16_t但不需要存在(如果平台一次只能使用16位,则必须定义typedef int16_t。)

现在将所有字符串包装在uint_least16_t的数组中,并确保您的代码不希望uint_least16_t的值包含在65535 ...