我有一个.h文件,它由我的构建脚本生成,#include由资源文件生成,但由于(tm)符号,它不会构建:
#define PRODUCT_NAME Acme Widget™ 1.2.3
我收到的错误是CommonAssemblyInfo.h(7): error RC2018: unknown character '0xe2'
。
显然我可以通过使用(TM)来解决它,但我更喜欢使用“正确”的符号。可以这样做吗?
更新
我应该更全面地描述这个问题,为此我道歉。事实证明,我省略了一个重要的细节:有问题的头文件被资源文件包含,因此错误来自资源编译器。我正在更新这篇文章的标题以反映这一事实。
答案 0 :(得分:1)
C11具有UTF-8编码的字符串文字的语法。对于您的特定字符串,它看起来像这样(假设源,或至少这部分,以UTF-8编码):
#define PRODUCT_NAME u8"Acme Widget™ 1.2.3"
C不提供其基本字符集之外的字符出现在宽/ Unicode字符串文字之外的源文件中,但某些实现可能会将它们作为扩展名接受。
另一种方法是将编码的字节嵌入到普通的字符串文字中,或者实际上嵌入到原始的宏替换文本中:
#define PRODUCT_NAME Acme Widget\xE2\x84\xA2 1.2.3
但是,省略字符串分隔符并没有多大用处,因为十六进制转义语法仅在字符串和整数字符文字的上下文中有意义。
然而,大多数可移植的都是使用Unicode转义,如@chux在评论中建议的那样。但是,在这种情况下,我认为将整个字符串作为utf-8字符串文字没有任何不利之处:
#define PRODUCT_NAME u8"Acme Widget\u2122 1.2.3"
答案 1 :(得分:1)
在Mac上(使用GCC 6.3.0运行macOS Sierra 10.12.3),在LANG=en_US.UTF-8
设置区域设置的终端中,以下变体全部编译:
#include <stdio.h>
#define PRODUCT_STRING "Acme Widget™ 1.2.3"
#define PRODUCT_UTF8 "Acme Widget\u2122 1.2.3"
#define PRODUCT_NAME Acme Widget™ 1.2.3
#define STRINGIFY(x) # x
#define CVT_TO_STRING(x) STRINGIFY(x)
int main(void)
{
puts(CVT_TO_STRING(PRODUCT_NAME));
puts(PRODUCT_STRING);
puts(PRODUCT_UTF8);
return 0;
}
汇编:
$ gcc -O3 -g -std=c11 -Wall -Wextra -Werror -Wmissing-prototypes \
> -Wstrict-prototypes -Wold-style-definition tm17.c -o tm17
$
输出,你不会感到惊讶,是:
Acme Widget™ 1.2.3
Acme Widget™ 1.2.3
Acme Widget™ 1.2.3
理论上,\u2122
是最好的(最便携的)符号。
我还测试了#define PRODUCT_NAME Acme Widget\u2122 1.2.3
;编译并生成相同的输出。
将Unicode转义添加到C99;您可能需要指定-std=c99
或-std=gnu99
(或使用C11代替)才能获得所需的结果。
答案 2 :(得分:0)
尝试:
Replace™for unicode \ u2122
使用引号
stream.js:74
throw er; // Unhandled stream error in pipe.
答案 3 :(得分:0)
事实证明Visual C ++资源编译器不理解UTF-8,但只知道ANSI和Unicode:
https://connect.microsoft.com/VisualStudio/feedback/details/214917/
RC编译器支持UTF-16。至于UTF-8,RC编译器目前不支持它。这种不方便的简单解决方法是使用Visual Studio另存为功能将rc文件转换为UTF-16。
该错误被关闭为&#34;设计&#34;在2006-10-24 - 十多年前。可惜UTF-8没有抓住...... / s
果然,当我将文件保存为Unicode时,一切都很顺利。