我有一个由我的构建脚本生成的.h文件,并由资源文件包含,但是由于(tm)符号:
,它不会构建。#define PRODUCT_NAME Acme Widget™ 1.2.3
我回来的错误是CommonAssemblyInfo.h(7): error RC2018: unknown character '0xe2'
。
显然,我可以使用(TM)可以解决它,但是我宁愿使用"正确"符号。可以以这种方式完成吗?
update
我应该在描述问题时更加完整,为此我深表歉意。事实证明,我省略了一个重要的细节:资源文件中包含有问题的标题文件,因此错误来自资源编译器。我正在更新这篇文章的标题以反映事实。
c11具有用于UTF-8编码字符串文字的语法。对于您的特定字符串,看起来像这样(假设源或至少该部分是在UTF-8中编码的):
#define PRODUCT_NAME u8"Acme Widget™ 1.2.3"
c不能为其基本字符之外的字符提供,以在宽/unicode字符串文字之外出现在源文件中,尽管某些实现可能会接受它们作为扩展。
一种替代方法是将编码的字节嵌入到普通的字符串文字中,或者确实嵌入到原始的宏替换文本中:
#define PRODUCT_NAME Acme WidgetxE2x84xA2 1.2.3
但是,省略字符串定界符没有太大用处,因为十六进制逃脱语法仅在字符串和整数字符文字的上下文中有意义。
最便携的是,正如@chux在评论中所建议的那样,将使用Unicode Escape。但是,在这种情况下,我认为将整个字符串视为UTF-8字符串文字:
没有任何缺点#define PRODUCT_NAME u8"Acme Widgetu2122 1.2.3"
在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 Widgetu2122 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 Widgetu2122 1.2.3
;
将Unicode Escapes添加到C99中;您可能需要指定-std=c99
或-std=gnu99
(或使用C11)以获取所需的结果。
尝试:
替换™for Unicode u2122
使用引号
#define PRODUCT_NAME "Acme Widgetu2122 1.2.3"
事实证明,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,将RC文件另存为功能。
十年前,该错误在2006-10-24上以"设计"的形式关闭。Pity UTF-8尚未抓住.../s
果然,当我将文件保存为Unicode时,一切都很好。