我使用utf8并需要将一个常量保存在字符数组中:
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
可能是 signed
或 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
)选项。
在某些实现中,char是无符号的,而CHAR_MAX为255(CHAR_MIN为0)。在其他情况下,char是有符号的,因此CHAR_MIN为-128,CHAR_MAX为127(例如,在Linux/PowerPC/32位和Linux/x86/32位上情况不同)。据我所知,标准没有禁止19位有符号字符。
char
的有符号性,那么您正在使用编译器的默认设置...这可能会在不同的编译器供应商(甚至是同一编译器的不同版本)之间发生变化。当您需要一个char
作为一个byte
时,您应该声明它,并且不要对编译器可能会做什么或不会做什么做出任何假设。 - Zac Howlandchar
不同于signed char
或unsigned char
,但它们在基本层面上非常接近,以至于在我15年的C++专业编程生涯中,我只需要区分它们一次。 - John Diblingchar
。我以前尝试过使用unsigned char
(因为我经常处理带有重音符号的字符):它根本不起作用(因为很多函数都需要char*
或std::string
,并且字符串字面值是char[]
),这会让读者感到困惑。 - James Kanzeunsigned char s = {0xE2,0x82,0xAC, 0};
char
都是带符号的,而且 CHAR_MAX
为 255(CHAR_MIN
为 0)。在其他一些实现中,char
是有符号的,所以 CHAR_MIN
为 -128,CHAR_MAX
为 127(例如,在 Linux/PowerPC/32 位和 Linux/x86/32 位上情况可能会有所不同)。 - Basile Starynkevitch虽然在代码中频繁使用强制类型转换可能会让人感到乏味,但对我来说,尽可能使用强类型是非常好的做法。
如上所述,当您指定类型“char”时,您正在邀请编译器选择编译器作者首选的内容(有符号或无符号)。我不是UTF-8的专家,但如果您不需要,就没有理由使您的代码不可移植。
至于您的常量,我曾经使用过默认将这种方式编写的常量转换为有符号整数的编译器,以及考虑上下文并相应解释它们的编译器。请注意,有符号和无符号之间的转换可能会溢出。对于相同数量的位,负数会溢出无符号数(显然),而带有设置了最高位的无符号数会溢出有符号数,因为最高位表示负数。
在这种情况下,您的编译器将您的常量视为无符号8位或更大,这意味着它们不适合作为有符号8位。我们都很感激编译器发出警告(至少我是)。
我的观点是,强制类型转换以显示您打算发生的事情是完全没有问题的。如果编译器允许您在有符号和无符号之间进行分配,那么无论变量还是常量都应该要求您进行强制类型转换。例如:
const int8_t a = (int8_t) 0xFF; // 将会是 -1
虽然在我的例子中,最好赋值为 -1。当你需要添加额外的转换时,它们要么有意义,要么你应该编写适合所分配类型的常量。
有没有一种方法可以混合这些内容?我想要一个宏定义 FX_RGB(R,G,B)
,将其变为一个常量字符串“\x01\xRR\xGG\xBB”,以便我可以执行以下操作:
const char* LED_text = "Hello " FX_RGB(0xff, 0xff, 0x80) "World";
并获得一个字符串:const char* LED_text = "Hello \x01\xff\xff\x80World";
const char s[] = u8"\u20AC";
? - Kerrek SB