如何在C中引用UTF-16字符?

如何在C中引用UTF-16字符?,c,utf-16,C,Utf 16,现在我正在为我的库编写一个C.头文件,它处理UTF-16字符 这个.h应该在MSVC/GCC中的Linux/windows32/64位上编译。 因为它是一个lib头,所以我不能坚持使用C99及更高版本。因此,我不能使用wchar\u t或uint16\u t。如何指定UTF-16变量 到目前为止,我得出了以下结论: #if _WIN32 typedef wchar_t char_UTF16; #else #if __GNUC__ typedef unsigned short

现在我正在为我的库编写一个C.头文件,它处理
UTF-16
字符

这个.h应该在
MSVC/GCC
中的
Linux/windows32/64位上编译。
因为它是一个lib头,所以我不能坚持使用
C99
及更高版本。因此,我不能使用
wchar\u t
uint16\u t
。如何指定
UTF-16
变量

到目前为止,我得出了以下结论:

#if _WIN32 
  typedef wchar_t char_UTF16;
#else 
  #if __GNUC__
    typedef unsigned short char_UTF16;
  #else
    #error "Compiler not supported"
  #endif
#endif

但我真的不认为这是最好的解决方案。

您可以以编译器不可知的方式尝试一些内置类型:

#include <limits.h>
#include <wchar.h>

#if (WCHAR_MAX==65535) && WCHAR_MIN==0
typedef wchar_t char_UTF16;
#elif USHRT_MAX==65535
typedef unsigned short char_UTF16;
#elif UINT_MAX==65535
typedef unsigned char_UTF16;
#else
#    error "Cannot find 16-bit type"
#endif
#包括
#包括
#如果(最大值=65535)和最小值=0
typedef wchar_t char_UTF16;
#elif USHRT_MAX==65535
typedef无符号短字符UTF16;
#elif UINT_MAX==65535
typedef无符号字符UTF16;
#否则
#错误“找不到16位类型”
#恩迪夫
(尝试
无符号长
没有意义,因为标准要求它至少32位宽)


。。。虽然我不确定您是否应该尝试
wchar\u t
,但我可能会直接选择数字类型,否则您的客户可能会认为,例如,宽字符是“正确的”为您的库键入,而事实上它们仅在Windows上。

您可以以与编译器无关的方式尝试某些内置类型:

#include <limits.h>
#include <wchar.h>

#if (WCHAR_MAX==65535) && WCHAR_MIN==0
typedef wchar_t char_UTF16;
#elif USHRT_MAX==65535
typedef unsigned short char_UTF16;
#elif UINT_MAX==65535
typedef unsigned char_UTF16;
#else
#    error "Cannot find 16-bit type"
#endif
#包括
#包括
#如果(最大值=65535)和最小值=0
typedef wchar_t char_UTF16;
#elif USHRT_MAX==65535
typedef无符号短字符UTF16;
#elif UINT_MAX==65535
typedef无符号字符UTF16;
#否则
#错误“找不到16位类型”
#恩迪夫
(尝试
无符号长
没有意义,因为标准要求它至少32位宽)


。。。虽然我不确定您是否应该尝试
wchar\u t
,但我可能会直接选择数字类型,否则您可能会让您的客户认为,例如,宽字符文本对于您的库是“正确”类型,而事实上它们仅在Windows上。您的反对理由不太清楚。utf-16中的编码元素采用16位,因此无符号短码在这两种情况下都可以正常工作。在win32中使用wchar\u t也可以,这会使调试器更智能。请记住,它是一种可变长度编码,一个代码点需要1或2个元素。或者,在windows上使用
wchar\t
,在其他任何地方使用
unsigned short
。它可能在不受支持的编译器上工作。。。(但这是最好的基本方法)。今天,有什么理由编写一个库,而它却不能自由地要求其客户机只使用符合17年前发布的标准的编译器?@user2854853:我的一个项目是标准C库。(你知道,
,所有这些好东西。)我不能给C99之前的编译器一个{bleep}{bleeep}{bleeep}。我很快就对排除C++**11**的环境失去了耐心……“因为它不是标准”——什么不是标准?C99当然是,尽管它已经被C11正式取代。你的反对理由还不太清楚。utf-16中的编码元素采用16位,因此无符号短码在这两种情况下都可以正常工作。在win32中使用wchar\u t也可以,这会使调试器更智能。请记住,它是一种可变长度编码,一个代码点需要1或2个元素。或者,在windows上使用
wchar\t
,在其他任何地方使用
unsigned short
。它可能在不受支持的编译器上工作。。。(但这是最好的基本方法)。今天,有什么理由编写一个库,而它却不能自由地要求其客户机只使用符合17年前发布的标准的编译器?@user2854853:我的一个项目是标准C库。(你知道,
,所有这些好东西。)我不能给C99之前的编译器一个{bleep}{bleeep}{bleeep}。我很快就对排除C++**11**的环境失去了耐心……“因为它不是标准”——什么不是标准?C99当然是,尽管它已经被C11正式取代。你对
char16\u t
的想法(它至少是16位的,可以与
\uu STDC\u UTF\u 16\u
u'A'
等字符常量一起使用)嗯,没有看到禁止
char16\u t
。IAC,尝试使用最好的可用类型,然后降级到越来越不理想的选择是最好的方法。顺便说一句,在
之后,不要认为
#elif UINT_MAX==65535
是可能的。建议重新排序:
#elif UINT_MAX==65535
然后
#elif USHRT_MAX==65535
。您对
char16_t
的想法(它至少是16位,可与
\u STDC\u UTF_16_
u'A'
等字符常量一起使用)。嗯,您没有看到禁止
char16_t
。IAC,尝试使用最好的可用类型,然后降级到越来越不理想的选择是最好的方法。顺便说一句,在
之后,不要认为
#elif UINT_MAX==65535
是可能的。建议重新订购:
#elif UINT_MAX==65535
然后
#elif USHRT_MAX==65535