简体   繁体   English

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

[英]How to initialize char array using hex numbers?

I use utf8 and have to save a constant in a char array:我使用 utf8 并且必须在 char 数组中保存一个常量:

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

However it gives me error:但是它给了我错误:

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

I have to cast all the hex numbers to char, which I feel tedious and don't smell good.我必须将所有的十六进制数字都转换为 char,我觉得这很乏味而且味道不好。 Is there any other proper way of doing this?有没有其他正确的方法来做到这一点?

char may be signed or unsigned (and the default is implementation specific). char可以是有signedunsigned (默认值是特定于实现的)。 You probably want你可能想要

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

or

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

or with many recent compilers (including GCC )或许多最近的编译器(包括GCC

  const char s[] = "€";

(a string literal is an array of char unless you give it some prefix) 字符串文字是一个char数组,除非你给它一些前缀)

See -funsigned-char (or -fsigned-char ) option of GCC.请参阅GCC 的 -funsigned-char (或-fsigned-char )选项。

On some implementations a char is unsigned and CHAR_MAX is 255 (and CHAR_MIN is 0).在某些实现中, charunsignedCHAR_MAX是 255(而CHAR_MIN是 0)。 On others char -s are signed so CHAR_MIN is -128 and CHAR_MAX is 127 (and eg things are different on Linux/PowerPC/32 bits and Linux/x86/32 bits).在其他情况下, char -s 是有signed因此CHAR_MIN为 -128, CHAR_MAX为 127(例如,Linux/PowerPC/32 位和 Linux/x86/32 位上的情况有所不同)。 AFAIK nothing in the standard prohibits 19 bits signed chars. AFAIK 标准中没有任何内容禁止 19 位有符号字符。

The short answer to your question is that you are overflowing a char .对您的问题的简短回答是您正在溢出一个char A char has the range of [-128, 127]. char的范围为 [-128, 127]。 0xE2 = 226 > 127. What you need to use is an unsigned char , which has a range of [0, 255]. 0xE2 = 226 > 127. 你需要使用的是一个unsigned char ,它的范围是 [0, 255]。

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

While it may well be tedious to be putting lots of casts in your code, it actually smells extremely GOOD to me to use as strong of typing as possible.虽然在您的代码中放置大量强制转换可能很乏味,但使用尽可能强的类型对我来说实际上闻起来非常好。

As noted above, when you specify type "char" you are inviting a compiler to choose whatever the compiler writer preferred (signed or unsigned).如上所述,当您指定类型“char”时,您是在邀请编译器选择编译器编写者喜欢的任何内容(有符号或无符号)。 I'm no expert on UTF-8, but there is no reason to make your code non-portable if you don't need to.我不是 UTF-8 方面的专家,但如果您不需要,没有理由让您的代码不可移植。

As far as your constants, I've used compilers that default constants written that way to signed ints, as well as compilers that consider the context and interpret them accordingly.就您的常量而言,我使用了以这种方式将默认常量写入带符号整数的编译器,以及考虑上下文并相应地解释它们的编译器。 Note that converting between signed and unsigned can overflow EITHER WAY.请注意,有符号和无符号之间的转换可能会溢出。 For the same number of bits, a negative overflows an unsigned (obviously) and an unsigned with the top bit set overflows a signed, because the top bit means negative.对于相同的位数,负数溢出无符号数(显然),无符号数的最高位设置溢出有符号数,因为最高位表示负数。

In this case, your compiler is taking your constants as unsigned 8 bit--OR LARGER--which means they don't fit as signed 8 bit.在这种情况下,您的编译器将您的常量视为无符号 8 位 - 或更大 - 这意味着它们不适合有符号 8 位。 And we are all grateful that the compiler complains (at least I am).我们都很感激编译器抱怨(至少我是)。

My perspective is, there is nothing at all bad about casting to show exactly what you intend to happen.我的观点是,用演员表来准确地展示你打算发生的事情并没有什么坏处。 And if a compiler lets you assign between signed and unsigned, it should require that you cast regardless of variables or constants.如果编译器允许您在有符号和无符号之间进行分配,则它应该要求您在不考虑变量或常量的情况下进行转换。 eg例如

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

although in my example, it would be better to assign -1.尽管在我的示例中,最好分配 -1。 When you are having to add extra casts, they either make sense, or you should code your constants so they make sense for the type you are assigning to.当您必须添加额外的强制转换时,它们要么有意义,要么您应该对常量进行编码,以便它们对您分配给的类型有意义。

Is there a way to mix these?有没有办法混合这些? I want a define macro FX_RGB(R,G,B) that makes a const string "\\x01\\xRR\\xGG\\xBB" so I can do the following: const char* LED_text = "Hello " FX_RGB(0xff, 0xff, 0x80) "World";我想要一个定义宏FX_RGB(R,G,B)来生成一个常量字符串 "\\x01\\xRR\\xGG\\xBB" 所以我可以执行以下操作: const char* LED_text = "Hello " FX_RGB(0xff, 0xff, 0x80) "World"; and get a sting: const char* LED_text = "Hello \\x01\\xff\\xff\\x80World";并得到一个刺痛: const char* LED_text = "Hello \\x01\\xff\\xff\\x80World";

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM