2017-02-28 47 views
1

我有得到我的构建脚本生成,并通过资源文件包含(#include).h文件,但由于(TM)符号的它不会建:Can one#定义包含资源文件的非ANSI字符的文字字符串吗?

#define PRODUCT_NAME Acme Widget™ 1.2.3 

我得到的回复是错误CommonAssemblyInfo.h(7): error RC2018: unknown character '0xe2'

很明显,我可以通过使用TM来解决它,但我更愿意使用“正确”符号。可以这样做吗?


UPDATE

我本来应该在描述问题和我道歉,更完整。事实证明,我忽略了一个重要的细节:所涉及的头文件正在被资源文件包含,因此错误来自资源编译器。我正在更新这篇文章的标题以反映事实。

+0

尝试一对引号。 – bmargulies

+3

一开始:为什么不在文本周围添加'''?它应该是一个字符串文字,然后你应该检查你的编码。具体问题:提供一个[mcve]你为什么要添加UTF-8标签?你确定这是UTF-8?编译器使用哪个输入字符集?哪个输出字符集? – Olaf

+0

原则上,你应该能够使用\ u2122来表示™(U + 2122或UTF-8中的十六进制字节E2 84 A2) –

回答

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。

该错误在2006年10月24日 - 十多年前被封为“按设计”。可惜UTF-8还没有赶上.../s

果然,当我将该文件保存为Unicode时,一切都很顺利。

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

也许''Acme Widget“u8”\ u2122“”1.2.3“'避免使用'™' – chux

+0

好建议@chux,尽管在这种情况下我没有看到任何优势来分隔UTF-8部分并依靠st环串联。 –

+1

同意这种情况。如果OP想要''... Widget™1 ...“'(无空格),则需要分离,因为”Widget \ u2112“不正确。通过隔离,作为一般风格,避免了这个错误。 – chux

1

在Mac(运行MacOS的塞拉利昂10.12.3与GCC 6.3.0),在终端与区域由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 escapes被添加到C99;您可能需要指定-std=c99-std=gnu99(或使用C11代替)以获取所需结果。

0

尝试:

更换™对Unicode \ u2122

使用引号

#define PRODUCT_NAME "Acme Widget\u2122 1.2.3"