比较字符与十六进制值

发布于 2024-12-26 07:41:05 字数 622 浏览 1 评论 0原文

最后一天,我的代码中出现了一个令人讨厌的错误,经过一番搜索后,该错误似乎与字符值和十六进制之间的比较有关。我的编译器是在 Windows 上运行的 gcc 4.4.1。 我在下面的简单代码中复制了这个问题:

char c1 = 0xFF; char c2 = 0xFE;
if(c1 == 0xFF && c2 == 0xFE)
{
    //do something
}

令人惊讶的是上面的代码没有进入循环。我完全不知道为什么,并且非常感谢对此的帮助。这太荒谬了,解决方案一定是(一如既往)我完全忽视的一个巨大错误。

如果我用无符号字符替换上面的内容,它就可以工作,但仅在某些情况下有效。我正在努力找出发生了什么事。此外,如果我将十六进制值转换为 char ,相比之下它会正确进入循环,如下所示:

if(c1 == (char)0xFF && c2 == (char)0xFE)
{
    //do something
}

这是什么意思?为什么会发生这种事?默认情况下,原始十六进制值是否解释为字符? 出于好奇,我在代码中第一次注意到它是将流的前 2 个字节与上述十六进制值及其相反的字节顺序标记进行比较。

任何帮助表示赞赏

For the last day I have had a nasty bug in my code which after some searching appears to be related to comparison between char values and hex. My compiler is gcc 4.4.1 running on Windows.
I replicated the problem in the simple code below:

char c1 = 0xFF; char c2 = 0xFE;
if(c1 == 0xFF && c2 == 0xFE)
{
    //do something
}

Surprisingly the code above does not get in the loop. I have absolutely no idea why and would really appreciate some help on this. It is so absurd that the solution must be (as always) a huge mistake on my part that I totally overlooked.

If I replace the above with unsigned chars it works, but only in some cases. I am struggling to find out what's going on. In addition if I cast the hex values to char in comparison it enters the loop correctly like so:

if(c1 == (char)0xFF && c2 == (char)0xFE)
{
    //do something
}

What does that mean? Why can it be happening? Isn't the raw hex value interpreted as a char by default?
For the curious the point in my code where I first noticed it is comparison of first 2 bytes of a stream with the above hex value and their reverse to idenity the Byte Order Mark.

Any help is appreciated

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

满地尘埃落定 2025-01-02 07:41:05

普通char 可以是有符号无符号。如果类型是unsigned,那么一切都会按您的预期工作。
如果类型是signed,则将0xFF分配给c1意味着执行比较时该值将提升为-1,但是0xFF 是常规正整数,因此 -1 == 0xFF 比较失败。

请注意,charsigned charunsigned char 类型是不同的,但其中两个具有相同的表示形式(两者之一是字符)。

Plain char can be signed or unsigned. If the type is unsigned, then all works as you'd expect.
If the type is signed, then assigning 0xFF to c1 means that the value will be promoted to -1 when the comparison is executed, but the 0xFF is a regular positive integer, so the comparison of -1 == 0xFF fails.

Note that the types char, signed char and unsigned char are distinct, but two of them have the same representation (and one of the two is char).

怎会甘心 2025-01-02 07:41:05

将字符与十六进制进行比较时,必须小心:

使用 == 运算符将 char 与 0x80 进行比较总是会导致 false?

我建议 C99 中引入这种语法,以确保

if(c1 == '\xFF' && c2 == '\xFE')
{
    // do something
}

避免强制转换,这是不必要的并且类型不安全。

它告诉编译器 0xFF 是一个 char 而不是 int,这将解决您的问题。

clang 编译器也会警告您:

常量 128 与类型 'char' 的表达式的比较始终为 false [-Werror,-Wtautological-constant-out-of-range-compare]

When comparing char to hex you must be careful:

Using the == operator to compare a char to 0x80 always results in false?

I would recommend this syntax introduced in C99 to be sure

if(c1 == '\xFF' && c2 == '\xFE')
{
    // do something
}

Avoid the cast, it's unnecessary and isn't type safe.

It tells the compiler that the 0xFF is a char rather than an int, this will solve your issue.

clang compiler will warn you about this also:

comparison of constant 128 with expression of type 'char' is always false [-Werror,-Wtautological-constant-out-of-range-compare]

倾`听者〃 2025-01-02 07:41:05

文字 0xff 不是 char,而是 int(有符号)。当您将其硬塞到 char 变量中时,它会很好地适合,但是根据您的 char 类型是有符号还是无符号,这将影响它在表达式中的升级方式(请参阅以下)。

在像 if (c1 == 0xff) 这样的表达式中,c1 变量将被提升为整数,因为 0xff 就是这样。 它的升级内容取决于它是否已签名。

最重要的是,您可以做两件事之一。

  1. 确保您使用signed char,以便它“符号扩展”为正确的int。我的意思是一个无符号的 char 0xff 将变成(对于 4 字节 int0x000000ff (所以它仍然是 255),但是一个有符号的字符将变为 0xffffffff(因此它仍然是 -1)。

  2. 将文字调整为与变量相同的类型,您已经使用 (char)oxff 执行此操作。

The literal 0xff is not a char, it's a int (signed). When you shoehorn that into a char variable, it will fit okay but, depending on whether your char type is signed or unsigned, this will affect how it's upgraded in expressions (see below).

In an expression like if (c1 == 0xff), the c1 variable will be promoted to an integer since that's what 0xff is. And what it's promoted to depends on whether it's signed or not.

Bottom line, you can do one of two things.

  1. Ensure that you use signed char so that it "sign-extends" to the correct int. By that I mean an unsigned char 0xff would become (for a 4-byte int) 0x000000ff (so it's still 255) but a signed one would become 0xffffffff (so it's still -1).

  2. Shoehorn the literal into the same type as the variable, which you're already doing with (char)oxff.

零度℉ 2025-01-02 07:41:05

字符 0xFE 将被转换为负整数。表达式中的常量将被转换为正整数。

The character 0xFE will he translated into a negative integer. The constants in the expression will be translated into positive integers.

夜司空 2025-01-02 07:41:05

我通过将变量转换为 UINT16(针对我的编译器进行了优化)解决了这个问题。在您的情况下,您会将 c1 和 c2 转换为 INT

char c1 = 0xFF; char c2 = 0xFE;
if((int)c1 == 0xFF && (int)c2 == 0xFE)
{
    //do something
}

I solved it by casting my variables to UINT16 (optimized for my compiler). In your case, you would be casting c1 and c2 as INT

char c1 = 0xFF; char c2 = 0xFE;
if((int)c1 == 0xFF && (int)c2 == 0xFE)
{
    //do something
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文