17

我使用 utf8 并且必须在 char 数组中保存一个常量:

const char s[] = {0xE2,0x82,0xAC, 0}; //the euro sign

但是它给了我错误:

test.cpp:15:40: error: narrowing conversion of ‘226’ from ‘int’ to ‘const char’ inside { } [-fpermissive]

我必须将所有的十六进制数字都转换为 char,我觉得这很乏味,而且味道不好。还有其他正确的方法吗?

4

4 回答 4

32

char可能是signedor unsigned(并且默认值是特定于实现的)。你可能想要

  const unsigned char s[] = {0xE2,0x82,0xAC, 0}; 

或者

  const char s[] = "\xe2\x82\xac";

或使用许多最近的编译器(包括GCC

  const char s[] = "€";

字符串文字是一个数组,char除非你给它一些前缀)

请参阅GCC 的 -funsigned-char (或-fsigned-char)选项。

在某些实现中,acharunsigned并且CHAR_MAX是 255(并且CHAR_MIN是 0)。在其他方面,char-s也是 -128 和127(例如,Linux/PowerPC/32 位和 Linux/x86/32 位的情况有所不同)。AFAIK 标准中没有任何内容禁止 19 位有符号字符。signedCHAR_MINCHAR_MAX

于 2013-10-31T19:53:30.447 回答
0

对您的问题的简短回答是您溢出了char. Achar的范围为 [-128, 127]。0xE2 = 226 > 127。您需要使用的是一个unsigned char,其范围为 [0, 255]。

unsigned char s = {0xE2,0x82,0xAC, 0};
于 2013-10-31T20:06:59.220 回答
0

有没有办法混合这些?我想要一个FX_RGB(R,G,B)创建 const 字符串 "\x01\xRR\xGG\xBB" 的定义宏,所以我可以执行以下操作: const char* LED_text = "Hello " FX_RGB(0xff, 0xff, 0x80) "World"; 并得到一个刺痛:const char* LED_text = "Hello \x01\xff\xff\x80World";

于 2021-12-06T19:13:51.283 回答
0

虽然在您的代码中放置大量强制转换可能很乏味,但对我来说,使用尽可能强的类型实际上闻起来非常好。

如上所述,当您指定类型“char”时,您是在邀请编译器选择编译器编写者喜欢的任何内容(有符号或无符号)。我不是 UTF-8 方面的专家,但如果你不需要,没有理由让你的代码不可移植。

至于您的常量,我使用了默认常量以这种方式写入有符号整数的编译器,以及考虑上下文并相应地解释它们的编译器。请注意,有符号和无符号之间的转换可能会溢出。对于相同的位数,负数会溢出无符号数(显然),并且设置了最高位的无符号数会溢出有符号数,因为最高位表示负数。

在这种情况下,您的编译器将您的常量视为无符号 8 位 - 或更大 - 这意味着它们不适合作为有符号 8 位。我们都感谢编译器抱怨(至少我是)。

我的观点是,通过选角来准确展示你打算发生的事情并没有什么不好。如果编译器允许您在有符号和无符号之间进行分配,它应该要求您强制转换,而不考虑变量或常量。例如

常量 int8_t a = (int8_t) 0xFF; // 将是 -1

尽管在我的示例中,最好分配-1。当您必须添加额外的强制转换时,它们要么有意义,要么您应该对常量进行编码,以便它们对您分配的类型有意义。

于 2016-11-03T23:08:43.697 回答