![](/img/trans.png)
[英]C++ misuse of template or problems of compilers string literal comparison with template
[英]When did C++ compilers start considering more than two hex digits in string literal character escapes?
我在C ++中有一个(生成的)文字字符串,可能包含需要使用\\x
表示法转义的字符。 例如:
char foo[] = "\xABEcho";
但是,g ++(版本4.1.2,如果它很重要)会抛出一个错误:
test.cpp:1: error: hex escape sequence out of range
编译器似乎将Ec
字符视为前面的十六进制数字的一部分(因为它们看起来像十六进制数字)。 由于四位十六进制数不适合char
,因此会引发错误。 显然,对于宽字符串文字L"\\xABEcho"
,第一个字符是U + ABEC,其次是L"ho"
。
在过去的几十年里,这似乎发生了变化,我从未注意到。 我几乎可以肯定,旧的C编译器只会在\\x
之后考虑两个十六进制数字,而不再看了。
我可以想到一个解决方法:
char foo[] = "\xAB""Echo";
但那有点难看。 所以我有三个问题:
这什么时候改变了?
为什么编译器只接受> 2位十六进制转义为宽字符串文字?
有没有比上述更难的解决方法?
我找到了问题的答案:
C ++一直都是这样(检查过Stroustrup第3版,之前没有任何内容)。 K&R第1版没有提到\\x
(当时唯一可用的角色是八进制)。 K&R第2版声明:
'\\xhh'
其中hh是一个或多个十六进制数字(0 ... 9,a ... f,A ... F)。
所以看起来这种行为自ANSI C以来就存在。
虽然编译器可能只接受> 2个字符作为宽字符串文字,但这会不必要地使语法复杂化。
确实有一个不太尴尬的解决方法:
char foo[] = "\«Echo";
\\u\u003c/code>转义符始终接受四个十六进制数字。
更新 :使用
\\u\u003c/code>并不适用于所有情况,因为大多数ASCII字符(由于某种原因)不允许使用
\\u\u003c/code>指定。
以下是海湾合作委员会的一个片段:
/* The standard permits $, @ and ` to be specified as UCNs. We use
hex escapes so that this also works with EBCDIC hosts. */
else if ((result < 0xa0
&& (result != 0x24 && result != 0x40 && result != 0x60))
|| (result & 0x80000000)
|| (result >= 0xD800 && result <= 0xDFFF))
{
cpp_error (pfile, CPP_DL_ERROR,
"%.*s is not a valid universal character",
(int) (str - base), base);
result = 1;
}
我通过使用\\ xnn指定以下char来解决这个问题。 不幸的是,只要[a..f]范围内有char,就必须使用它。 恩。 “\\ xnneceg”替换为“\\ xnn \\ x65 \\ x63 \\ x65g”
我很确定C ++一直都是这样的。 在任何情况下, CHAR_BIT
可能大于8,在这种情况下'\\xABE'
或'\\xABEc'
可能有效。
这些是宽字符文字。
char foo[] = "\x00ABEcho";
可能会更好。
这里有一些信息,而不是gcc,但似乎仍然适用。
此链接包括重要的一行:
指定
\\xnn
在wchar_t的字符串文字相当于指定\\x00nn
这也可能有所帮助。
http://www.gnu.org/s/hello/manual/libc/Extended-Char-Intro.html#Extended-Char-Intro
我也遇到了这个问题。 我发现我可以在第二个十六进制数字的末尾添加一个空格,然后通过使用退格符'\\ b'跟踪空格来消除空间。 不完全可取,但它似乎工作。
“Julius C \\ xE6sar是frana \\ xE7 \\ bais的征服者”
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.