如何使用十六进制数初始化char数组?

时间:2013-10-31 19:52:00

标签: c++ unicode

我使用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,这让我感到乏味,并且闻起来不太好。还有其他正确的方法吗?

3 个答案:

答案 0 :(得分:22)

char可能是signedunsigned(默认情况下是特定于实施的)。你可能想要

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

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

(a string literalchar的数组,除非你给它一些前缀)

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

在某些实现中,charunsignedCHAR_MAX为255(CHAR_MIN为0)。在其他char上 - s是signed,因此CHAR_MIN是-128而CHAR_MAX是127(例如Linux / PowerPC / 32位和Linux / x86 /上的情况有所不同32位)。 AFAIK标准中没有任何内容禁止19位签名字符。

答案 1 :(得分:0)

您的问题的简短回答是,您正在溢出charchar的范围为[-128,127]。 0xE2 = 226> 127.你需要使用的是unsigned char,其范围为[0,255]。

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

答案 2 :(得分:0)

虽然在你的代码中加入大量的强制转换可能会很繁琐,但实际上我觉得使用尽可能强大的键入效果非常好。

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

就你的常量而言,我使用的编译器默认使用那些写入签名整数的常量,以及考虑上下文并相应地解释它们的编译器。请注意,有符号和无符号之间的转换可能会溢出EITHER WAY。对于相同数量的位,负数溢出无符号(显然)和无符号,顶部位溢出有符号,因为最高位表示负数。

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

我的观点是,铸造以确切展示你打算发生什么并没有什么不好。如果编译器允许您在有符号和无符号之间进行分配,则应该要求您在不管变量或常量的情况下进行转换。例如

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

虽然在我的例子中,分配-1会更好。当你不得不添加额外的强制转换时,它们要么有意义,要么你应该对你的常量进行编码,使它们对你所分配的类型有意义。